X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Ffrontend%2Fparser.c;h=c82a514a00e7ddb4831805dafbbed8c9c618888e;hp=76382d34b099756b09348e0afa67ab013a9ab7ca;hb=5e20183e0a2264e0aed972ceff913374ab970248;hpb=495dfe8178398c64d78f1476fe505fb0e36eefdc diff --git a/src/frontend/parser.c b/src/frontend/parser.c index 76382d3..c82a514 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -34,7 +34,9 @@ #include "core/store.h" #include "utils/llist.h" +#include "utils/strbuf.h" +#include #include /* @@ -43,17 +45,23 @@ static int scanner_init(const char *input, int len, - sdb_fe_yyscan_t *scanner, sdb_fe_yyextra_t *extra) + sdb_fe_yyscan_t *scanner, sdb_fe_yyextra_t *extra, + sdb_strbuf_t *errbuf) { - if (! input) + if (! input) { + sdb_strbuf_sprintf(errbuf, "Missing scanner input"); return -1; + } memset(extra, 0, sizeof(*extra)); extra->parsetree = sdb_llist_create(); extra->mode = SDB_PARSE_DEFAULT; + extra->errbuf = errbuf; - if (! extra->parsetree) + if (! extra->parsetree) { + sdb_strbuf_sprintf(errbuf, "Failed to allocate parse-tree"); return -1; + } *scanner = sdb_fe_scanner_init(input, len, extra); if (! scanner) { @@ -68,13 +76,14 @@ scanner_init(const char *input, int len, */ sdb_llist_t * -sdb_fe_parse(const char *query, int len) +sdb_fe_parse(const char *query, int len, sdb_strbuf_t *errbuf) { sdb_fe_yyscan_t scanner; sdb_fe_yyextra_t yyextra; + sdb_llist_iter_t *iter; int yyres; - if (scanner_init(query, len, &scanner, &yyextra)) + if (scanner_init(query, len, &scanner, &yyextra, errbuf)) return NULL; yyres = sdb_fe_yyparse(scanner); @@ -84,11 +93,23 @@ sdb_fe_parse(const char *query, int len) sdb_llist_destroy(yyextra.parsetree); return NULL; } + + iter = sdb_llist_get_iter(yyextra.parsetree); + while (sdb_llist_iter_has_next(iter)) { + sdb_conn_node_t *node; + node = SDB_CONN_NODE(sdb_llist_iter_get_next(iter)); + if (sdb_fe_analyze(node, errbuf)) { + sdb_llist_iter_destroy(iter); + sdb_llist_destroy(yyextra.parsetree); + return NULL; + } + } + sdb_llist_iter_destroy(iter); return yyextra.parsetree; } /* sdb_fe_parse */ sdb_store_matcher_t * -sdb_fe_parse_matcher(const char *expr, int len) +sdb_fe_parse_matcher(const char *cond, int len, sdb_strbuf_t *errbuf) { sdb_fe_yyscan_t scanner; sdb_fe_yyextra_t yyextra; @@ -98,10 +119,10 @@ sdb_fe_parse_matcher(const char *expr, int len) int yyres; - if (scanner_init(expr, len, &scanner, &yyextra)) + if (scanner_init(cond, len, &scanner, &yyextra, errbuf)) return NULL; - yyextra.mode = SDB_PARSE_EXPR; + yyextra.mode = SDB_PARSE_COND; yyres = sdb_fe_yyparse(scanner); sdb_fe_scanner_destroy(scanner); @@ -112,19 +133,60 @@ sdb_fe_parse_matcher(const char *expr, int len) } node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0)); - if (! node) + if (! node) { + sdb_strbuf_sprintf(errbuf, "Empty matcher expression '%s'", cond); + sdb_llist_destroy(yyextra.parsetree); return NULL; + } - if (node->cmd == CONNECTION_EXPR) - m = CONN_MATCHER(node)->matcher; - else - m = NULL; - + assert(node->cmd == SDB_CONNECTION_MATCHER); + m = CONN_MATCHER(node)->matcher; CONN_MATCHER(node)->matcher = NULL; + sdb_llist_destroy(yyextra.parsetree); sdb_object_deref(SDB_OBJ(node)); return m; } /* sdb_fe_parse_matcher */ +sdb_store_expr_t * +sdb_fe_parse_expr(const char *expr, int len, sdb_strbuf_t *errbuf) +{ + sdb_fe_yyscan_t scanner; + sdb_fe_yyextra_t yyextra; + + sdb_conn_node_t *node; + sdb_store_expr_t *e; + + int yyres; + + if (scanner_init(expr, len, &scanner, &yyextra, errbuf)) + return NULL; + + yyextra.mode = SDB_PARSE_EXPR; + + yyres = sdb_fe_yyparse(scanner); + sdb_fe_scanner_destroy(scanner); + + if (yyres) { + sdb_llist_destroy(yyextra.parsetree); + return NULL; + } + + node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0)); + if (! node) { + sdb_strbuf_sprintf(errbuf, "Empty expression '%s'", expr); + sdb_llist_destroy(yyextra.parsetree); + return NULL; + } + + assert(node->cmd == SDB_CONNECTION_EXPR); + e = CONN_EXPR(node)->expr; + CONN_EXPR(node)->expr = NULL; + + sdb_llist_destroy(yyextra.parsetree); + sdb_object_deref(SDB_OBJ(node)); + return e; +} /* sdb_fe_parse_expr */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */