X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=3180167fe2d98256637078338be98baf1e5368f8;hp=92b55ebbd509eb9d62c975a3866c5aa67ce07534;hb=5e20183e0a2264e0aed972ceff913374ab970248;hpb=8075debb62385a01df5b8d344ad590cf0575c2eb diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 92b55eb..3180167 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -48,10 +48,7 @@ */ static sdb_store_matcher_t * -name_matcher(const char *type_name, const char *cmp, sdb_store_expr_t *expr); - -static sdb_store_matcher_t * -name_iter_matcher(int m_type, const char *type_name, const char *cmp, +name_iter_matcher(int m_type, int type, const char *cmp, sdb_store_expr_t *expr); /* @@ -66,6 +63,8 @@ sdb_fe_yyget_extra(sdb_fe_yyscan_t scanner); void sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); +void +sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...); /* quick access to the current parse tree */ #define pt sdb_fe_yyget_extra(scanner)->parsetree @@ -73,6 +72,9 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); /* quick access to the parser mode */ #define parser_mode sdb_fe_yyget_extra(scanner)->mode +/* quick access to the parser's error buffer */ +#define errbuf sdb_fe_yyget_extra(scanner)->errbuf + #define MODE_TO_STRING(m) \ (((m) == SDB_PARSE_DEFAULT) ? "statement" \ : ((m) == SDB_PARSE_COND) ? "condition" \ @@ -92,6 +94,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %union { const char *sstr; /* static string */ char *str; + int integer; sdb_data_t data; sdb_time_t datetime; @@ -112,6 +115,10 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %token CMP_LT CMP_LE CMP_GE CMP_GT ALL ANY IN %token CONCAT +%token HOST_T HOSTS_T SERVICE_T SERVICES_T METRIC_T METRICS_T +%token ATTRIBUTE_T ATTRIBUTES_T +%token NAME_T LAST_UPDATE_T AGE_T INTERVAL_T BACKEND_T + %token START END /* NULL token */ @@ -156,6 +163,10 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %type expression +%type object_type object_type_plural +%type iterable +%type field + %type cmp %type data @@ -175,11 +186,9 @@ statements: { /* only accepted in default parse mode */ if (parser_mode != SDB_PARSE_DEFAULT) { - char errmsg[1024]; - snprintf(errmsg, sizeof(errmsg), + sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting %s"), MODE_TO_STRING(parser_mode)); - sdb_fe_yyerror(&yylloc, scanner, errmsg); sdb_object_deref(SDB_OBJ($3)); YYABORT; } @@ -194,11 +203,9 @@ statements: { /* only accepted in default parse mode */ if (parser_mode != SDB_PARSE_DEFAULT) { - char errmsg[1024]; - snprintf(errmsg, sizeof(errmsg), + sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, unexpected statement, " "expecting %s"), MODE_TO_STRING(parser_mode)); - sdb_fe_yyerror(&yylloc, scanner, errmsg); sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -213,11 +220,9 @@ statements: { /* only accepted in condition parse mode */ if (! (parser_mode & SDB_PARSE_COND)) { - char errmsg[1024]; - snprintf(errmsg, sizeof(errmsg), + sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, unexpected condition, " "expecting %s"), MODE_TO_STRING(parser_mode)); - sdb_fe_yyerror(&yylloc, scanner, errmsg); sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -232,11 +237,9 @@ statements: { /* only accepted in expression parse mode */ if (! (parser_mode & SDB_PARSE_EXPR)) { - char errmsg[1024]; - snprintf(errmsg, sizeof(errmsg), + sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, unexpected expression, " "expecting %s"), MODE_TO_STRING(parser_mode)); - sdb_fe_yyerror(&yylloc, scanner, errmsg); sdb_object_deref(SDB_OBJ($1)); YYABORT; } @@ -245,7 +248,7 @@ statements: sdb_conn_node_t *n; n = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_expr_t, conn_expr_destroy)); - n->cmd = CONNECTION_EXPR; + n->cmd = SDB_CONNECTION_EXPR; CONN_EXPR(n)->expr = $1; sdb_llist_append(pt, SDB_OBJ(n)); @@ -275,27 +278,26 @@ statement: * Retrieve detailed information about a single host. */ fetch_statement: - FETCH IDENTIFIER STRING filter_clause - { - /* TODO: support other types as well */ - if (strcasecmp($2, "host")) { - char errmsg[strlen($2) + 32]; - snprintf(errmsg, sizeof(errmsg), - YY_("unknown data-source %s"), $2); - sdb_fe_yyerror(&yylloc, scanner, errmsg); - free($2); $2 = NULL; - free($3); $3 = NULL; - sdb_object_deref(SDB_OBJ($4)); - YYABORT; - } - + FETCH object_type STRING filter_clause + { $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_fetch_t, conn_fetch_destroy)); - CONN_FETCH($$)->type = SDB_HOST; - CONN_FETCH($$)->name = $3; + CONN_FETCH($$)->type = $2; + CONN_FETCH($$)->host = $3; + CONN_FETCH($$)->name = NULL; CONN_FETCH($$)->filter = CONN_MATCHER($4); - $$->cmd = CONNECTION_FETCH; - free($2); $2 = NULL; + $$->cmd = SDB_CONNECTION_FETCH; + } + | + FETCH object_type STRING '.' STRING filter_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_fetch_t, conn_fetch_destroy)); + CONN_FETCH($$)->type = $2; + CONN_FETCH($$)->host = $3; + CONN_FETCH($$)->name = $5; + CONN_FETCH($$)->filter = CONN_MATCHER($6); + $$->cmd = SDB_CONNECTION_FETCH; } ; @@ -305,25 +307,13 @@ fetch_statement: * Returns a list of all hosts in the store. */ list_statement: - LIST IDENTIFIER filter_clause - { - int type = sdb_store_parse_object_type_plural($2); - if ((type < 0) || (type == SDB_ATTRIBUTE)) { - char errmsg[strlen($2) + 32]; - snprintf(errmsg, sizeof(errmsg), - YY_("unknown data-source %s"), $2); - sdb_fe_yyerror(&yylloc, scanner, errmsg); - free($2); $2 = NULL; - sdb_object_deref(SDB_OBJ($3)); - YYABORT; - } - + LIST object_type_plural filter_clause + { $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_list_t, conn_list_destroy)); - CONN_LIST($$)->type = type; + CONN_LIST($$)->type = $2; CONN_LIST($$)->filter = CONN_MATCHER($3); - $$->cmd = CONNECTION_LIST; - free($2); $2 = NULL; + $$->cmd = SDB_CONNECTION_LIST; } ; @@ -333,27 +323,14 @@ list_statement: * Returns detailed information about matching condition. */ lookup_statement: - LOOKUP IDENTIFIER matching_clause filter_clause - { - /* TODO: support other types as well */ - if (strcasecmp($2, "hosts")) { - char errmsg[strlen($2) + 32]; - snprintf(errmsg, sizeof(errmsg), - YY_("unknown data-source %s"), $2); - sdb_fe_yyerror(&yylloc, scanner, errmsg); - free($2); $2 = NULL; - sdb_object_deref(SDB_OBJ($3)); - sdb_object_deref(SDB_OBJ($4)); - YYABORT; - } - + LOOKUP object_type_plural matching_clause filter_clause + { $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_lookup_t, conn_lookup_destroy)); - CONN_LOOKUP($$)->type = SDB_HOST; + CONN_LOOKUP($$)->type = $2; CONN_LOOKUP($$)->matcher = CONN_MATCHER($3); CONN_LOOKUP($$)->filter = CONN_MATCHER($4); - $$->cmd = CONNECTION_LOOKUP; - free($2); $2 = NULL; + $$->cmd = SDB_CONNECTION_LOOKUP; } ; @@ -381,7 +358,7 @@ timeseries_statement: CONN_TS($$)->metric = $4; CONN_TS($$)->opts.start = $5; CONN_TS($$)->opts.end = $6; - $$->cmd = CONNECTION_TIMESERIES; + $$->cmd = SDB_CONNECTION_TIMESERIES; } ; @@ -411,7 +388,7 @@ condition: $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, conn_matcher_t, conn_matcher_destroy)); - $$->cmd = CONNECTION_MATCHER; + $$->cmd = SDB_CONNECTION_MATCHER; CONN_MATCHER($$)->matcher = $1; } ; @@ -458,24 +435,15 @@ compare_matcher: sdb_object_deref(SDB_OBJ($3)); } | - IDENTIFIER cmp expression - { - $$ = name_matcher($1, $2, $3); - free($1); $1 = NULL; - sdb_object_deref(SDB_OBJ($3)); - } - | - ANY IDENTIFIER cmp expression + ANY iterable cmp expression { $$ = name_iter_matcher(MATCHER_ANY, $2, $3, $4); - free($2); $2 = NULL; sdb_object_deref(SDB_OBJ($4)); } | - ALL IDENTIFIER cmp expression + ALL iterable cmp expression { $$ = name_iter_matcher(MATCHER_ALL, $2, $3, $4); - free($2); $2 = NULL; sdb_object_deref(SDB_OBJ($4)); } | @@ -547,26 +515,14 @@ expression: sdb_object_deref(SDB_OBJ($3)); $3 = NULL; } | - '.' IDENTIFIER + field { - int field = sdb_store_parse_field_name($2); - free($2); $2 = NULL; - $$ = sdb_store_expr_fieldvalue(field); + $$ = sdb_store_expr_fieldvalue($1); } | - IDENTIFIER '[' STRING ']' + ATTRIBUTE_T '[' STRING ']' { - if (strcasecmp($1, "attribute")) { - char errmsg[strlen($1) + strlen($3) + 32]; - snprintf(errmsg, sizeof(errmsg), - YY_("unknown value %s[%s]"), $1, $3); - sdb_fe_yyerror(&yylloc, scanner, errmsg); - free($1); $1 = NULL; - free($3); $3 = NULL; - YYABORT; - } $$ = sdb_store_expr_attrvalue($3); - free($1); $1 = NULL; free($3); $3 = NULL; } | @@ -577,6 +533,44 @@ expression: } ; +object_type: + HOST_T { $$ = SDB_HOST; } + | + SERVICE_T { $$ = SDB_SERVICE; } + | + METRIC_T { $$ = SDB_METRIC; } + ; + +object_type_plural: + HOSTS_T { $$ = SDB_HOST; } + | + SERVICES_T { $$ = SDB_SERVICE; } + | + METRICS_T { $$ = SDB_METRIC; } + ; + +iterable: + SERVICE_T { $$ = SDB_SERVICE; } + | + METRIC_T { $$ = SDB_METRIC; } + | + ATTRIBUTE_T { $$ = SDB_ATTRIBUTE; } + | + BACKEND_T { $$ = SDB_FIELD_BACKEND; } + ; + +field: + NAME_T { $$ = SDB_FIELD_NAME; } + | + LAST_UPDATE_T { $$ = SDB_FIELD_LAST_UPDATE; } + | + AGE_T { $$ = SDB_FIELD_AGE; } + | + INTERVAL_T { $$ = SDB_FIELD_INTERVAL; } + | + BACKEND_T { $$ = SDB_FIELD_BACKEND; } + ; + cmp: CMP_EQUAL { $$ = "="; } | @@ -631,10 +625,8 @@ interval_elem: unit = sdb_strpunit($2); if (! unit) { - char errmsg[strlen($2) + 32]; - snprintf(errmsg, sizeof(errmsg), + sdb_fe_yyerrorf(&yylloc, scanner, YY_("invalid time unit %s"), $2); - sdb_fe_yyerror(&yylloc, scanner, errmsg); free($2); $2 = NULL; YYABORT; } @@ -657,45 +649,38 @@ void sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg) { sdb_log(SDB_LOG_ERR, "frontend: parse error: %s", msg); + sdb_strbuf_sprintf(errbuf, "%s", msg); } /* sdb_fe_yyerror */ -static sdb_store_matcher_t * -name_matcher(const char *type_name, const char *cmp, sdb_store_expr_t *expr) +void +sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...) { - int type = sdb_store_parse_object_type(type_name); - sdb_store_matcher_op_cb cb = sdb_store_parse_matcher_op(cmp); - sdb_store_expr_t *e; - sdb_store_matcher_t *m; - assert(cb); - - /* TODO: this only works as long as queries - * are limited to hosts */ - if (type != SDB_HOST) - return NULL; - - e = sdb_store_expr_fieldvalue(SDB_FIELD_NAME); - m = cb(e, expr); - sdb_object_deref(SDB_OBJ(e)); - return m; -} /* name_matcher */ + va_list ap, aq; + va_start(ap, fmt); + va_copy(aq, ap); + sdb_vlog(SDB_LOG_ERR, fmt, ap); + sdb_strbuf_vsprintf(errbuf, "%s", aq); + va_end(ap); +} /* sdb_fe_yyerrorf */ static sdb_store_matcher_t * -name_iter_matcher(int m_type, const char *type_name, const char *cmp, +name_iter_matcher(int m_type, int type, const char *cmp, sdb_store_expr_t *expr) { - int type = sdb_store_parse_object_type(type_name); sdb_store_matcher_op_cb cb = sdb_store_parse_matcher_op(cmp); sdb_store_expr_t *e; sdb_store_matcher_t *m, *tmp = NULL; assert(cb); - /* TODO: this only works as long as queries - * are limited to hosts */ + /* hosts are never iterable */ if (type == SDB_HOST) { return NULL; } - e = sdb_store_expr_fieldvalue(SDB_FIELD_NAME); + if (type == SDB_FIELD_BACKEND) + e = sdb_store_expr_fieldvalue(type); + else + e = sdb_store_expr_fieldvalue(SDB_FIELD_NAME); m = cb(e, expr); if (m_type == MATCHER_ANY) tmp = sdb_store_any_matcher(type, m);