X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=c2440e8a16a585b8dcbf5b441cb42bc57e48765b;hb=969580ce8ca1badeb140492349b7c1541cf40b8f;hp=c3ee0af37886d3391d37f0d8fd425a586d0257c1;hpb=b5c0396e79bf2c0fbd03e96ca0654a4545cbf936;p=sysdb.git diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index c3ee0af..c2440e8 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -32,6 +32,7 @@ #include "frontend/grammar.h" #include "core/store.h" +#include "core/store-private.h" #include "utils/error.h" #include "utils/llist.h" @@ -69,21 +70,40 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); sdb_llist_t *list; sdb_conn_node_t *node; + + sdb_store_matcher_t *m; } %start statements %token SCANNER_ERROR +%token AND OR NOT WHERE +%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX + +%token FETCH LIST LOOKUP + %token IDENTIFIER STRING -%token FETCH LIST + +/* Precedence (lowest first): */ +%left OR +%left AND +%left NOT +%left CMP_EQUAL CMP_NEQUAL +%left CMP_REGEX CMP_NREGEX +%left '(' ')' +%left '.' %type statements %type statement fetch_statement list_statement + lookup_statement expression +%type matcher + compare_matcher + %% statements: @@ -94,6 +114,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting expression")); + sdb_object_deref(SDB_OBJ($3)); YYABORT; } @@ -110,6 +131,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting expression")); + sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -126,6 +148,7 @@ statements: sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected expression, " "expecting statement")); + sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -141,34 +164,35 @@ statement: | list_statement | + lookup_statement + | /* empty */ { $$ = NULL; } ; +/* + * FETCH ; + * + * Retrieve detailed information about a single host. + */ fetch_statement: - FETCH IDENTIFIER - { - $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, - conn_fetch_t, conn_fetch_destroy)); - CONN_FETCH($$)->name = strdup($2); - $$->cmd = CONNECTION_FETCH; - free($2); - $2 = NULL; - } - | FETCH STRING { $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_fetch_t, conn_fetch_destroy)); CONN_FETCH($$)->name = strdup($2); $$->cmd = CONNECTION_FETCH; - free($2); - $2 = NULL; + free($2); $2 = NULL; } ; +/* + * LIST; + * + * Returns a list of all hosts in the store. + */ list_statement: LIST { @@ -178,23 +202,127 @@ list_statement: } ; +/* + * LOOKUP WHERE ; + * + * Returns detailed information about matching expression. + */ +lookup_statement: + LOOKUP IDENTIFIER WHERE expression + { + /* TODO: support other types as well */ + if (strcasecmp($2, "hosts")) { + char errmsg[strlen($2) + 32]; + 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; + } + + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_lookup_t, conn_lookup_destroy)); + CONN_LOOKUP($$)->matcher = CONN_MATCHER($4); + $$->cmd = CONNECTION_LOOKUP; + free($2); $2 = NULL; + } + ; + expression: - IDENTIFIER + matcher { - $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL, - conn_node_matcher_t)); + if (! $1) { + /* TODO: improve error reporting */ + sdb_fe_yyerror(&yylloc, scanner, + YY_("syntax error, invalid expression")); + YYABORT; + } + + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_node_matcher_t, conn_matcher_destroy)); $$->cmd = CONNECTION_EXPR; - /* XXX: this is just a placeholder for now */ - CONN_MATCHER($$)->matcher = sdb_store_host_matcher($1, - /* name_re = */ NULL, /* service = */ NULL, - /* attr = */ NULL); - free($1); - $1 = NULL; + 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 + { + $$ = $1; + } + ; + +/* + * . + * + * Parse matchers comparing object attributes with a value. + */ +compare_matcher: + IDENTIFIER '.' IDENTIFIER CMP_EQUAL 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_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); + free($1); $1 = NULL; + 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) {