summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ddb6411)
raw | patch | inline | side by side (parent: ddb6411)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 6 Apr 2014 11:28:21 +0000 (13:28 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 6 Apr 2014 11:28:21 +0000 (13:28 +0200) |
src/frontend/grammar.y | patch | blob | history | |
src/frontend/scanner.l | patch | blob | history | |
t/frontend/parser_test.c | patch | blob | history |
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 6c52b74907b17163d1c15c7890f9f85d0ed959bf..fd268baf3a9c6ce5126891c9ff6edbcc8af16e4f 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%token SCANNER_ERROR
-%token WHERE
+%token AND OR WHERE
%token CMP_EQUAL CMP_REGEX
%token <str> IDENTIFIER STRING
%token <node> FETCH LIST LOOKUP
+/* Precedence (lowest first): */
+%left OR
+%left AND
+%left CMP_EQUAL
+%left CMP_REGEX
+
%type <list> statements
%type <node> statement
fetch_statement
lookup_statement
expression
-%type <m> compare_matcher
+%type <m> matcher
+ compare_matcher
%%
;
expression:
- compare_matcher
+ matcher
{
sdb_store_matcher_t *m = $1;
if (! m) {
conn_node_matcher_t));
$$->cmd = CONNECTION_EXPR;
- if (M(m)->type == MATCHER_HOST)
+ if ((M(m)->type == MATCHER_HOST)
+ || (M(m)->type == MATCHER_AND)
+ || (M(m)->type == MATCHER_OR))
CONN_MATCHER($$)->matcher = m;
else if (M(m)->type == MATCHER_SERVICE)
CONN_MATCHER($$)->matcher = sdb_store_host_matcher(NULL,
CONN_MATCHER($$)->matcher = sdb_store_host_matcher(NULL,
/* name_re = */ NULL, /* service = */ NULL,
/* attr = */ m);
+ else {
+ char errbuf[1024];
+ snprintf(errbuf, sizeof(errbuf),
+ YY_("syntax error, unexpected matcher type %d"),
+ M(m)->type);
+ sdb_fe_yyerror(&yylloc, scanner, errbuf);
+ YYABORT;
+ }
+ }
+ ;
+
+matcher:
+ matcher AND matcher
+ {
+ $$ = sdb_store_con_matcher($1, $3);
+ }
+ |
+ matcher OR matcher
+ {
+ $$ = sdb_store_dis_matcher($1, $3);
+ }
+ |
+ compare_matcher
+ {
+ $$ = $1;
}
;
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index 1e371f45668435d509dd4ddf942ec196f547ba76..9eec4de6c455e3dadd99fe586c2d4e68ba324395 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
{identifier} {
/* XXX: simplify handling of reserved words */
- if (! strcasecmp(yytext, "FETCH"))
+ if (! strcasecmp(yytext, "AND"))
+ return AND;
+ else if (! strcasecmp(yytext, "FETCH"))
return FETCH;
else if (! strcasecmp(yytext, "LIST"))
return LIST;
else if (! strcasecmp(yytext, "LOOKUP"))
return LOOKUP;
+ else if (! strcasecmp(yytext, "OR"))
+ return OR;
else if (! strcasecmp(yytext, "WHERE"))
return WHERE;
index 4b177328c084483edc1c74d7e167cf89533a8db3..1a7dc2bb3370de382d49b1b61a66f023bc868c79 100644 (file)
--- a/t/frontend/parser_test.c
+++ b/t/frontend/parser_test.c
sdb_conn_state_t expected_cmd;
} golden_data[] = {
/* empty commands */
- { NULL, -1, -1, 0 },
- { "", -1, 0, 0 },
- { ";", -1, 0, 0 },
- { ";;", -1, 0, 0 },
+ { NULL, -1, -1, 0 },
+ { "", -1, 0, 0 },
+ { ";", -1, 0, 0 },
+ { ";;", -1, 0, 0 },
/* valid commands */
- { "FETCH 'host'", -1, 1, CONNECTION_FETCH },
- { "LIST", -1, 1, CONNECTION_LIST },
- { "LIST -- comment", -1, 1, CONNECTION_LIST },
- { "LIST;", -1, 1, CONNECTION_LIST },
- { "LIST; INVALID", 5, 1, CONNECTION_LIST },
+ { "FETCH 'host'", -1, 1, CONNECTION_FETCH },
+ { "LIST", -1, 1, CONNECTION_LIST },
+ { "LIST -- comment", -1, 1, CONNECTION_LIST },
+ { "LIST;", -1, 1, CONNECTION_LIST },
+ { "LIST; INVALID", 5, 1, CONNECTION_LIST },
{ "LOOKUP hosts WHERE "
- "host.name = 'host'", -1, 1, CONNECTION_LOOKUP },
+ "host.name = 'host'", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "host.name =~ 'p' AND "
+ "service.name =~ 'p'", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "host.name =~ 'p' AND "
+ "service.name =~ 'p' OR "
+ "service.name =~ 'r'", -1, 1, CONNECTION_LOOKUP },
/* comments */
- { "/* some comment */", -1, 0, 0 },
- { "-- another comment", -1, 0, 0 },
+ { "/* some comment */", -1, 0, 0 },
+ { "-- another comment", -1, 0, 0 },
/* syntax errors */
- { "INVALID", -1, -1, 0 },
- { "FETCH host", -1, -1, 0 },
- { "LIST; INVALID", 8, -1, 0 },
- { "/* some incomplete", -1, -1, 0 },
+ { "INVALID", -1, -1, 0 },
+ { "FETCH host", -1, -1, 0 },
+ { "LIST; INVALID", 8, -1, 0 },
+ { "/* some incomplete", -1, -1, 0 },
- { "LOOKUP hosts", -1, -1, 0 },
+ { "LOOKUP hosts", -1, -1, 0 },
{ "LOOKUP foo WHERE "
- "host.name = 'host'", -1, -1, 0 },
+ "host.name = 'host'", -1, -1, 0 },
};
size_t i;
{ "host.name = 'localhost'", -1, 0 },
{ "host.name = 'localhost' -- foo", -1, 0 },
{ "host.name = 'host' <garbage>", 18, 0 },
+ { "host.name =~ 'pattern' AND "
+ "service.name =~ 'pattern'", -1, 0 },
+ { "host.name =~ 'pattern' OR "
+ "service.name =~ 'pattern'", -1, 0 },
/* syntax errors */
{ "LIST", -1, -1 },