ast.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "ast.h"
  17. #include "lexer.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include <libubox/utils.h>
  23. struct jp_opcode *
  24. jp_alloc_op(struct jp_state *s, int type, int num, char *str, ...)
  25. {
  26. va_list ap;
  27. char *ptr;
  28. struct jp_opcode *newop, *child;
  29. newop = calloc_a(sizeof(*newop),
  30. str ? &ptr : NULL, str ? strlen(str) + 1 : 0);
  31. if (!newop)
  32. {
  33. fprintf(stderr, "Out of memory\n");
  34. exit(127);
  35. }
  36. newop->type = type;
  37. newop->num = num;
  38. if (str)
  39. newop->str = strcpy(ptr, str);
  40. va_start(ap, str);
  41. while ((child = va_arg(ap, void *)) != NULL)
  42. if (!newop->down)
  43. newop->down = child;
  44. else
  45. append_op(newop->down, child);
  46. va_end(ap);
  47. newop->next = s->pool;
  48. s->pool = newop;
  49. return newop;
  50. }
  51. void
  52. jp_free(struct jp_state *s)
  53. {
  54. struct jp_opcode *op, *tmp;
  55. for (op = s->pool; op;)
  56. {
  57. tmp = op->next;
  58. free(op);
  59. op = tmp;
  60. }
  61. free(s);
  62. }
  63. struct jp_state *
  64. jp_parse(const char *expr)
  65. {
  66. struct jp_state *s;
  67. struct jp_opcode *op;
  68. const char *ptr = expr;
  69. void *pParser;
  70. int len = strlen(expr);
  71. int mlen = 0;
  72. s = calloc(1, sizeof(*s));
  73. if (!s)
  74. return NULL;
  75. pParser = ParseAlloc(malloc);
  76. if (!pParser)
  77. return NULL;
  78. while (len > 0)
  79. {
  80. op = jp_get_token(s, ptr, &mlen);
  81. if (mlen < 0)
  82. {
  83. s->error_code = mlen;
  84. goto out;
  85. }
  86. if (op)
  87. Parse(pParser, op->type, op, s);
  88. len -= mlen;
  89. ptr += mlen;
  90. s->off += mlen;
  91. }
  92. Parse(pParser, 0, NULL, s);
  93. out:
  94. ParseFree(pParser, free);
  95. return s;
  96. }