X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fparser.c;h=c82a514a00e7ddb4831805dafbbed8c9c618888e;hb=695324de797b55cf12d8a66bd3612e78bc1235af;hp=037550fbddd731bf4bd84c51c8d126d50466ff16;hpb=ae32792b881853979265e41b49866be9ea2d6b2c;p=sysdb.git diff --git a/src/frontend/parser.c b/src/frontend/parser.c index 037550f..c82a514 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -31,33 +31,99 @@ #include "frontend/parser.h" #include "frontend/grammar.h" +#include "core/store.h" + #include "utils/llist.h" +#include "utils/strbuf.h" +#include #include +/* + * private helper functions + */ + +static int +scanner_init(const char *input, int len, + sdb_fe_yyscan_t *scanner, sdb_fe_yyextra_t *extra, + sdb_strbuf_t *errbuf) +{ + 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) { + sdb_strbuf_sprintf(errbuf, "Failed to allocate parse-tree"); + return -1; + } + + *scanner = sdb_fe_scanner_init(input, len, extra); + if (! scanner) { + sdb_llist_destroy(extra->parsetree); + return -1; + } + return 0; +} /* scanner_init */ + /* * public API */ sdb_llist_t * -sdb_fe_parse(const char *query) +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 (! query) + if (scanner_init(query, len, &scanner, &yyextra, errbuf)) return NULL; - memset(&yyextra, 0, sizeof(yyextra)); - yyextra.parsetree = sdb_llist_create(); + yyres = sdb_fe_yyparse(scanner); + sdb_fe_scanner_destroy(scanner); - scanner = sdb_fe_scanner_init(query, &yyextra); - if (! scanner) { + if (yyres) { 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 *cond, int len, sdb_strbuf_t *errbuf) +{ + sdb_fe_yyscan_t scanner; + sdb_fe_yyextra_t yyextra; + + sdb_conn_node_t *node; + sdb_store_matcher_t *m; + + int yyres; + + if (scanner_init(cond, len, &scanner, &yyextra, errbuf)) + return NULL; + + yyextra.mode = SDB_PARSE_COND; + yyres = sdb_fe_yyparse(scanner); sdb_fe_scanner_destroy(scanner); @@ -65,8 +131,62 @@ sdb_fe_parse(const char *query) sdb_llist_destroy(yyextra.parsetree); return NULL; } - return yyextra.parsetree; -} /* sdb_fe_parse */ + + node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0)); + if (! node) { + sdb_strbuf_sprintf(errbuf, "Empty matcher expression '%s'", cond); + sdb_llist_destroy(yyextra.parsetree); + return 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 : */