diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 323fe4feadba40715c3b43c95d0f5d93441de564..31b71a0eba7665b94de03bd47c50a0cd989ff24e 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
*/
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int m_type, sdb_store_expr_t *iter, const char *cmp,
sdb_store_expr_t *expr);
/*
#define MODE_TO_STRING(m) \
(((m) == SDB_PARSE_DEFAULT) ? "statement" \
: ((m) == SDB_PARSE_COND) ? "condition" \
- : ((m) == SDB_PARSE_EXPR) ? "expression" \
+ : ((m) == SDB_PARSE_ARITH) ? "arithmetic expression" \
: "UNKNOWN")
%}
%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 NAME_T LAST_UPDATE_T AGE_T INTERVAL_T BACKEND_T VALUE_T
%token LAST UPDATE
%type <m> matcher
compare_matcher
-%type <expr> expression object_expression
+%type <expr> expression arithmetic_expression object_expression
%type <integer> object_type object_type_plural
-%type <integer> iterable
%type <integer> field
%type <sstr> cmp
expression
{
/* only accepted in expression parse mode */
- if (! (parser_mode & SDB_PARSE_EXPR)) {
+ if (! (parser_mode & SDB_PARSE_ARITH)) {
sdb_fe_yyerrorf(&yylloc, scanner,
YY_("syntax error, unexpected expression, "
"expecting %s"), MODE_TO_STRING(parser_mode));
sdb_object_deref(SDB_OBJ($3));
}
|
- ANY iterable cmp expression
+ ANY expression cmp expression
{
$$ = name_iter_matcher(MATCHER_ANY, $2, $3, $4);
+ sdb_object_deref(SDB_OBJ($2));
sdb_object_deref(SDB_OBJ($4));
}
|
- ALL iterable cmp expression
+ ALL expression cmp expression
{
$$ = name_iter_matcher(MATCHER_ALL, $2, $3, $4);
+ sdb_object_deref(SDB_OBJ($2));
sdb_object_deref(SDB_OBJ($4));
}
|
;
expression:
+ arithmetic_expression
+ {
+ if (! $1) {
+ /* we should have better error messages here
+ * TODO: maybe let the analyzer handle this instead */
+ sdb_fe_yyerror(&yylloc, scanner,
+ YY_("syntax error, invalid arithmetic expression"));
+ YYABORT;
+ }
+ $$ = $1;
+ }
+ |
+ object_expression
+ {
+ $$ = $1;
+ }
+ |
+ data
+ {
+ $$ = sdb_store_expr_constvalue(&$1);
+ sdb_data_free_datum(&$1);
+ }
+ ;
+
+arithmetic_expression:
'(' expression ')'
{
$$ = $2;
sdb_object_deref(SDB_OBJ($1)); $1 = NULL;
sdb_object_deref(SDB_OBJ($3)); $3 = NULL;
}
- |
- object_expression
- {
- $$ = $1;
- }
- |
- data
- {
- $$ = sdb_store_expr_constvalue(&$1);
- sdb_data_free_datum(&$1);
- }
;
object_expression:
sdb_object_deref(SDB_OBJ($3));
}
|
+ ATTRIBUTE_T '.' object_expression
+ {
+ $$ = sdb_store_expr_typed(SDB_ATTRIBUTE, $3);
+ sdb_object_deref(SDB_OBJ($3));
+ }
+ |
field
{
$$ = sdb_store_expr_fieldvalue($1);
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; }
|
INTERVAL_T { $$ = SDB_FIELD_INTERVAL; }
|
BACKEND_T { $$ = SDB_FIELD_BACKEND; }
+ |
+ VALUE_T { $$ = SDB_FIELD_VALUE; }
;
cmp:
va_start(ap, fmt);
va_copy(aq, ap);
sdb_vlog(SDB_LOG_ERR, fmt, ap);
- sdb_strbuf_vsprintf(errbuf, "%s", aq);
+ sdb_strbuf_vsprintf(errbuf, fmt, aq);
va_end(ap);
} /* sdb_fe_yyerrorf */
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int type, sdb_store_expr_t *iter, const char *cmp,
sdb_store_expr_t *expr)
{
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);
- /* hosts are never iterable */
- if (type == SDB_HOST) {
- return NULL;
- }
-
- 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);
- else if (m_type == MATCHER_ALL)
- tmp = sdb_store_all_matcher(type, m);
+ m = cb(NULL, expr);
+ if (type == MATCHER_ANY)
+ tmp = sdb_store_any_matcher(iter, m);
+ else if (type == MATCHER_ALL)
+ tmp = sdb_store_all_matcher(iter, m);
sdb_object_deref(SDB_OBJ(m));
- sdb_object_deref(SDB_OBJ(e));
return tmp;
} /* name_iter_matcher */