X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=57174290b00dc97c00aa50d9e1d6841ff45f3dad;hb=90ada5c7c86cf280b2a4468e285671e9314e0d29;hp=74e28dd837f7e8eb7a819e1a0a4ed2ebda032ffb;hpb=b9bc76b71c4e4e1174ba1a8af3e13d53840b7e16;p=sysdb.git diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 74e28dd..5717429 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -75,6 +75,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); sdb_conn_node_t *node; sdb_store_matcher_t *m; + sdb_store_expr_t *expr; } %start statements @@ -84,6 +85,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %token AND OR IS NOT MATCHING %token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX %token CMP_LT CMP_LE CMP_GE CMP_GT +%token CONCAT /* NULL token */ %token NULL_T @@ -101,7 +103,10 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %left CMP_EQUAL CMP_NEQUAL %left CMP_LT CMP_LE CMP_GE CMP_GT %nonassoc CMP_REGEX CMP_NREGEX +%left CONCAT %nonassoc IS +%left '+' '-' +%left '*' '/' '%' %left '(' ')' %left '.' @@ -110,17 +115,20 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); fetch_statement list_statement lookup_statement - expression + condition %type matcher compare_matcher +%type expression + %type op %type data + interval interval_elem %destructor { free($$); } -%destructor { sdb_object_deref(SDB_OBJ($$)); } +%destructor { sdb_object_deref(SDB_OBJ($$)); } %% @@ -131,7 +139,7 @@ statements: if (parser_mode != SDB_PARSE_DEFAULT) { sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " - "expecting expression")); + "expecting condition")); sdb_object_deref(SDB_OBJ($3)); YYABORT; } @@ -148,7 +156,7 @@ statements: if (parser_mode != SDB_PARSE_DEFAULT) { sdb_fe_yyerror(&yylloc, scanner, YY_("syntax error, unexpected statement, " - "expecting expression")); + "expecting condition")); sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -159,12 +167,12 @@ statements: } } | - expression + condition { - /* only accept this in expression parse mode */ - if (! (parser_mode & SDB_PARSE_EXPR)) { + /* only accept this in condition parse mode */ + if (! (parser_mode & SDB_PARSE_COND)) { sdb_fe_yyerror(&yylloc, scanner, - YY_("syntax error, unexpected expression, " + YY_("syntax error, unexpected condition, " "expecting statement")); sdb_object_deref(SDB_OBJ($1)); YYABORT; @@ -221,12 +229,12 @@ list_statement: ; /* - * LOOKUP MATCHING ; + * LOOKUP MATCHING ; * - * Returns detailed information about matching expression. + * Returns detailed information about matching condition. */ lookup_statement: - LOOKUP IDENTIFIER MATCHING expression + LOOKUP IDENTIFIER MATCHING condition { /* TODO: support other types as well */ if (strcasecmp($2, "hosts")) { @@ -247,13 +255,13 @@ lookup_statement: } ; -expression: +condition: matcher { if (! $1) { /* TODO: improve error reporting */ sdb_fe_yyerror(&yylloc, scanner, - YY_("syntax error, invalid expression")); + YY_("syntax error, invalid condition")); YYABORT; } @@ -302,19 +310,26 @@ matcher: * Parse matchers comparing object attributes with a value. */ compare_matcher: - IDENTIFIER op data + ':' IDENTIFIER op expression { - $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, &$3); + $$ = sdb_store_matcher_parse_field_cmp($2, $3, $4); + free($2); $2 = NULL; + sdb_object_deref(SDB_OBJ($4)); + } + | + IDENTIFIER op expression + { + $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, $3); free($1); $1 = NULL; - sdb_data_free_datum(&$3); + sdb_object_deref(SDB_OBJ($3)); } | - IDENTIFIER '.' IDENTIFIER op data + IDENTIFIER '.' IDENTIFIER op expression { - $$ = sdb_store_matcher_parse_cmp($1, $3, $4, &$5); + $$ = sdb_store_matcher_parse_cmp($1, $3, $4, $5); free($1); $1 = NULL; free($3); $3 = NULL; - sdb_data_free_datum(&$5); + sdb_object_deref(SDB_OBJ($5)); } | IDENTIFIER '.' IDENTIFIER IS NULL_T @@ -337,6 +352,54 @@ compare_matcher: } ; +expression: + '(' expression ')' + { + $$ = $2; + } + | + expression '+' expression + { + $$ = sdb_store_expr_create(SDB_DATA_ADD, $1, $3); + sdb_object_deref(SDB_OBJ($1)); $1 = NULL; + sdb_object_deref(SDB_OBJ($3)); $3 = NULL; + } + | + expression '-' expression + { + $$ = sdb_store_expr_create(SDB_DATA_SUB, $1, $3); + sdb_object_deref(SDB_OBJ($1)); $1 = NULL; + sdb_object_deref(SDB_OBJ($3)); $3 = NULL; + } + | + expression '*' expression + { + $$ = sdb_store_expr_create(SDB_DATA_MUL, $1, $3); + sdb_object_deref(SDB_OBJ($1)); $1 = NULL; + sdb_object_deref(SDB_OBJ($3)); $3 = NULL; + } + | + expression '/' expression + { + $$ = sdb_store_expr_create(SDB_DATA_DIV, $1, $3); + sdb_object_deref(SDB_OBJ($1)); $1 = NULL; + sdb_object_deref(SDB_OBJ($3)); $3 = NULL; + } + | + expression '%' expression + { + $$ = sdb_store_expr_create(SDB_DATA_MOD, $1, $3); + sdb_object_deref(SDB_OBJ($1)); $1 = NULL; + sdb_object_deref(SDB_OBJ($3)); $3 = NULL; + } + | + data + { + $$ = sdb_store_expr_constvalue(&$1); + sdb_data_free_datum(&$1); + } + ; + op: CMP_EQUAL { $$ = "="; } | @@ -361,6 +424,44 @@ data: INTEGER { $$ = $1; } | FLOAT { $$ = $1; } + | + interval { $$ = $1; } + ; + +interval: + interval interval_elem + { + $$.data.datetime = $1.data.datetime + $2.data.datetime; + } + | + interval_elem { $$ = $1; } + ; + +interval_elem: + INTEGER IDENTIFIER + { + sdb_time_t unit = 1; + + unit = sdb_strpunit($2); + if (! unit) { + char errmsg[strlen($2) + 32]; + snprintf(errmsg, sizeof(errmsg), + YY_("invalid time unit %s"), $2); + sdb_fe_yyerror(&yylloc, scanner, errmsg); + free($2); $2 = NULL; + YYABORT; + } + free($2); $2 = NULL; + + $$.type = SDB_TYPE_DATETIME; + $$.data.datetime = (sdb_time_t)$1.data.integer * unit; + + if ($1.data.integer < 0) { + sdb_fe_yyerror(&yylloc, scanner, + YY_("syntax error, negative intervals not supported")); + YYABORT; + } + } ; %%