X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=450a20f34218ef1df4db9e713bb3b0247cddc0bb;hb=8e7384947ee57bbbe58e210be4f6ec04ef8ff508;hp=abc51656934edcffc8c6f32ddf7320f985541d77;hpb=495dfe8178398c64d78f1476fe505fb0e36eefdc;p=sysdb.git diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index abc5165..450a20f 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -78,9 +78,9 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %token SCANNER_ERROR -%token AND OR WHERE +%token AND OR NOT WHERE -%token CMP_EQUAL CMP_REGEX +%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX %token IDENTIFIER STRING %token FETCH LIST LOOKUP @@ -88,8 +88,11 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); /* Precedence (lowest first): */ %left OR %left AND -%left CMP_EQUAL -%left CMP_REGEX +%left NOT +%left CMP_EQUAL CMP_NEQUAL +%left CMP_REGEX CMP_NREGEX +%left '(' ')' +%left '.' %type statements %type statement @@ -229,8 +232,7 @@ lookup_statement: expression: matcher { - sdb_store_matcher_t *m = $1; - if (! m) { + if (! $1) { /* TODO: improve error reporting */ sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, invalid expression")); @@ -240,40 +242,34 @@ expression: $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_node_matcher_t, conn_matcher_destroy)); $$->cmd = CONNECTION_EXPR; - - if ((M(m)->type == MATCHER_HOST) - || (M(m)->type == MATCHER_AND) - || (M(m)->type == MATCHER_OR)) - CONN_MATCHER($$)->matcher = m; - else if (M(m)->type == MATCHER_SERVICE) - CONN_MATCHER($$)->matcher = sdb_store_host_matcher(NULL, - /* name_re = */ NULL, /* service = */ m, - /* attr = */ NULL); - else if (M(m)->type == MATCHER_ATTR) - CONN_MATCHER($$)->matcher = sdb_store_host_matcher(NULL, - /* name_re = */ NULL, /* service = */ NULL, - /* attr = */ m); - else { - char errbuf[1024]; - snprintf(errbuf, sizeof(errbuf), - YY_("syntax error, unexpected matcher type %d"), - M(m)->type); - sdb_object_deref(SDB_OBJ($$)); - sdb_fe_yyerror(&yylloc, scanner, errbuf); - YYABORT; - } + CONN_MATCHER($$)->matcher = $1; } ; matcher: + '(' matcher ')' + { + $$ = $2; + } + | matcher AND matcher { $$ = sdb_store_con_matcher($1, $3); + sdb_object_deref(SDB_OBJ($1)); + sdb_object_deref(SDB_OBJ($3)); } | matcher OR matcher { $$ = sdb_store_dis_matcher($1, $3); + sdb_object_deref(SDB_OBJ($1)); + sdb_object_deref(SDB_OBJ($3)); + } + | + NOT matcher + { + $$ = sdb_store_inv_matcher($2); + sdb_object_deref(SDB_OBJ($2)); } | compare_matcher @@ -297,6 +293,15 @@ compare_matcher: free($5); $5 = NULL; } | + IDENTIFIER '.' IDENTIFIER CMP_NEQUAL STRING + { + $$ = sdb_store_matcher_parse_cmp($1, $3, "!=", $5); + /* TODO: simplify memory management in the parser */ + free($1); $1 = NULL; + free($3); $3 = NULL; + free($5); $5 = NULL; + } + | IDENTIFIER '.' IDENTIFIER CMP_REGEX STRING { $$ = sdb_store_matcher_parse_cmp($1, $3, "=~", $5); @@ -304,10 +309,20 @@ compare_matcher: free($3); $3 = NULL; free($5); $5 = NULL; } + | + IDENTIFIER '.' IDENTIFIER CMP_NREGEX STRING + { + $$ = sdb_store_matcher_parse_cmp($1, $3, "!~", $5); + free($1); $1 = NULL; + free($3); $3 = NULL; + free($5); $5 = NULL; + } ; %% +/* XXX: on parse errors, allocated objects, strings, etc. need to be freed */ + void sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg) {