diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2013-12-29 18:03:10 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2013-12-29 18:03:10 +0000 |
commit | bb372e308e2332766d038cef7bcdf74df7b0e31c (patch) | |
tree | 3193b449d204cd4467fdc5d9fbbd595a127a94ad /parser.y | |
parent | 054eb236c524a237f7cd156e8e71151b1b4e0ace (diff) | |
download | jsonpath-bb372e308e2332766d038cef7bcdf74df7b0e31c.tar.gz |
eliminate global variables and use a private parser/lexer state
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 100 |
1 files changed, 58 insertions, 42 deletions
@@ -15,45 +15,61 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <stdio.h> +#include <stdlib.h> #include <stdarg.h> +#include <string.h> + #include <libubox/utils.h> -#include "lexer.h" #include "parser.h" -static struct jp_opcode *op_pool = NULL; static struct jp_opcode *append_op(struct jp_opcode *a, struct jp_opcode *b); -int yyparse(struct jp_opcode **tree, const char **error); -void yyerror(struct jp_opcode **expr, const char **error, const char *msg); +int yylex(struct jp_state *s); +void *yy_scan_string (const char *str); +int yylex_destroy(void); + +int yyparse(struct jp_state *s); +void yyerror(struct jp_state *s, const char *msg); %} %output "parser.c" %defines "parser.h" -%parse-param { struct jp_opcode **expr } -%parse-param { const char **error } +%parse-param { struct jp_state *s } +%lex-param { struct jp_state *s } %code provides { -#ifndef JP_OPCODE -# define JP_OPCODE - struct jp_opcode { - int type; - struct jp_opcode *next; - struct jp_opcode *down; - struct jp_opcode *sibling; - char *str; - int num; - }; -#endif +#ifndef __PARSER_H_ +#define __PARSER_H_ + +struct jp_opcode { + int type; + struct jp_opcode *next; + struct jp_opcode *down; + struct jp_opcode *sibling; + char *str; + int num; +}; + +struct jp_state { + struct jp_opcode *pool; + struct jp_opcode *path; + const char *error; + char str_buf[128]; + char *str_ptr; +}; -struct jp_opcode *_jp_alloc_op(int type, int num, char *str, ...); -#define jp_alloc_op(type, num, str, ...) _jp_alloc_op(type, num, str, ##__VA_ARGS__, NULL) +struct jp_opcode *_jp_alloc_op(struct jp_state *s, int type, int num, char *str, ...); +#define jp_alloc_op(type, num, str, ...) _jp_alloc_op(s, type, num, str, ##__VA_ARGS__, NULL) -struct jp_opcode *jp_parse(const char *expr, const char **error); -void jp_free(void); +struct jp_state *jp_parse(const char *expr); +void jp_free(struct jp_state *s); + +#endif } @@ -74,7 +90,7 @@ void jp_free(void); %% input - : expr { *expr = $1; } + : expr { s->path = $1; } ; expr @@ -139,10 +155,9 @@ unary_exp %% void -yyerror(struct jp_opcode **expr, const char **error, const char *msg) +yyerror(struct jp_state *s, const char *msg) { - *error = msg; - jp_free(); + s->error = msg; } static struct jp_opcode * @@ -159,7 +174,7 @@ append_op(struct jp_opcode *a, struct jp_opcode *b) } struct jp_opcode * -_jp_alloc_op(int type, int num, char *str, ...) +_jp_alloc_op(struct jp_state *s, int type, int num, char *str, ...) { va_list ap; char *ptr; @@ -190,42 +205,43 @@ _jp_alloc_op(int type, int num, char *str, ...) va_end(ap); - newop->next = op_pool; - op_pool = newop; + newop->next = s->pool; + s->pool = newop; return newop; } -struct jp_opcode * -jp_parse(const char *expr, const char **error) +struct jp_state * +jp_parse(const char *expr) { - void *buf; - struct jp_opcode *tree; + struct jp_state *s; + + s = calloc(1, sizeof(*s)); + + if (!s) + return NULL; - buf = yy_scan_string(expr); + yy_scan_string(expr); - if (yyparse(&tree, error)) - tree = NULL; - else - *error = NULL; + if (yyparse(s)) + s->path = NULL; - yy_delete_buffer(buf); yylex_destroy(); - return tree; + return s; } void -jp_free(void) +jp_free(struct jp_state *s) { struct jp_opcode *op, *tmp; - for (op = op_pool; op;) + for (op = s->pool; op;) { tmp = op->next; free(op); op = tmp; } - op_pool = NULL; + free(s); } |