X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=74e28dd837f7e8eb7a819e1a0a4ed2ebda032ffb;hb=b9bc76b71c4e4e1174ba1a8af3e13d53840b7e16;hp=6c52b74907b17163d1c15c7890f9f85d0ed959bf;hpb=c63a274a489e53a9e84e9772839a16a1c2a3b2b8;p=sysdb.git diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 6c52b74..74e28dd 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -63,11 +63,14 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %locations %error-verbose %expect 0 -%name-prefix="sdb_fe_yy" +%name-prefix "sdb_fe_yy" %union { + const char *sstr; /* static string */ char *str; + sdb_data_t data; + sdb_llist_t *list; sdb_conn_node_t *node; @@ -78,12 +81,29 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %token SCANNER_ERROR -%token WHERE +%token AND OR IS NOT MATCHING +%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX +%token CMP_LT CMP_LE CMP_GE CMP_GT + +/* NULL token */ +%token NULL_T -%token CMP_EQUAL CMP_REGEX +%token FETCH LIST LOOKUP %token IDENTIFIER STRING -%token FETCH LIST LOOKUP + +%token INTEGER FLOAT + +/* Precedence (lowest first): */ +%left OR +%left AND +%right NOT +%left CMP_EQUAL CMP_NEQUAL +%left CMP_LT CMP_LE CMP_GE CMP_GT +%nonassoc CMP_REGEX CMP_NREGEX +%nonassoc IS +%left '(' ')' +%left '.' %type statements %type statement @@ -92,7 +112,15 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); lookup_statement expression -%type compare_matcher +%type matcher + compare_matcher + +%type op + +%type data + +%destructor { free($$); } +%destructor { sdb_object_deref(SDB_OBJ($$)); } %% @@ -104,6 +132,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting expression")); + sdb_object_deref(SDB_OBJ($3)); YYABORT; } @@ -120,6 +149,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting expression")); + sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -136,6 +166,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected expression, " "expecting statement")); + sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -190,12 +221,12 @@ list_statement: ; /* - * LOOKUP WHERE ; + * LOOKUP MATCHING ; * * Returns detailed information about matching expression. */ lookup_statement: - LOOKUP IDENTIFIER WHERE expression + LOOKUP IDENTIFIER MATCHING expression { /* TODO: support other types as well */ if (strcasecmp($2, "hosts")) { @@ -203,6 +234,8 @@ lookup_statement: snprintf(errmsg, sizeof(errmsg), YY_("unknown table %s"), $2); sdb_fe_yyerror(&yylloc, scanner, errmsg); + free($2); $2 = NULL; + sdb_object_deref(SDB_OBJ($4)); YYABORT; } @@ -215,30 +248,51 @@ lookup_statement: ; expression: - compare_matcher + 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")); YYABORT; } - $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL, - conn_node_matcher_t)); + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_node_matcher_t, conn_matcher_destroy)); $$->cmd = CONNECTION_EXPR; + CONN_MATCHER($$)->matcher = $1; + } + ; - if (M(m)->type == MATCHER_HOST) - 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); +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 + { + $$ = $1; } ; @@ -248,22 +302,65 @@ expression: * Parse matchers comparing object attributes with a value. */ compare_matcher: - IDENTIFIER '.' IDENTIFIER CMP_EQUAL STRING + IDENTIFIER op data + { + $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, &$3); + free($1); $1 = NULL; + sdb_data_free_datum(&$3); + } + | + IDENTIFIER '.' IDENTIFIER op data { - $$ = sdb_store_matcher_parse_cmp($1, $3, "=", $5); - /* TODO: simplify memory management in the parser */ + $$ = sdb_store_matcher_parse_cmp($1, $3, $4, &$5); free($1); $1 = NULL; free($3); $3 = NULL; - free($5); $5 = NULL; + sdb_data_free_datum(&$5); } | - IDENTIFIER '.' IDENTIFIER CMP_REGEX STRING + IDENTIFIER '.' IDENTIFIER IS NULL_T { - $$ = sdb_store_matcher_parse_cmp($1, $3, "=~", $5); + $$ = sdb_store_matcher_parse_cmp($1, $3, "IS", NULL); free($1); $1 = NULL; free($3); $3 = NULL; - free($5); $5 = NULL; } + | + IDENTIFIER '.' IDENTIFIER IS NOT NULL_T + { + sdb_store_matcher_t *m; + m = sdb_store_matcher_parse_cmp($1, $3, "IS", NULL); + free($1); $1 = NULL; + free($3); $3 = NULL; + + /* sdb_store_inv_matcher return NULL if m==NULL */ + $$ = sdb_store_inv_matcher(m); + sdb_object_deref(SDB_OBJ(m)); + } + ; + +op: + CMP_EQUAL { $$ = "="; } + | + CMP_NEQUAL { $$ = "!="; } + | + CMP_REGEX { $$ = "=~"; } + | + CMP_NREGEX { $$ = "!~"; } + | + CMP_LT { $$ = "<"; } + | + CMP_LE { $$ = "<="; } + | + CMP_GE { $$ = ">="; } + | + CMP_GT { $$ = ">"; } + ; + +data: + STRING { $$.type = SDB_TYPE_STRING; $$.data.string = $1; } + | + INTEGER { $$ = $1; } + | + FLOAT { $$ = $1; } ; %%