diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index ef88272d6b237f9885ca30761891ca3e00ab9437..551d1714d7a12cf86b64aea6834b4e4dd782dd89 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%{
+#include "frontend/connection-private.h"
#include "frontend/parser.h"
#include "frontend/grammar.h"
+
+#include "core/store.h"
+
#include "utils/error.h"
+#include "utils/llist.h"
#include <stdio.h>
+int
+sdb_fe_yylex(YYSTYPE *yylval, YYLTYPE *yylloc, sdb_fe_yyscan_t yyscanner);
+
+sdb_fe_yyextra_t *
+sdb_fe_yyget_extra(sdb_fe_yyscan_t scanner);
+
void
sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
+/* quick access to the current parse tree */
+#define pt sdb_fe_yyget_extra(scanner)->parsetree
+
+/* quick access to the parser mode */
+#define parser_mode sdb_fe_yyget_extra(scanner)->mode
+
%}
%pure-parser
%expect 0
%name-prefix="sdb_fe_yy"
+%union {
+ char *str;
+
+ sdb_llist_t *list;
+ sdb_conn_node_t *node;
+}
+
%start statements
%token SCANNER_ERROR
-%token IDENTIFIER
-%token LIST
+%token <str> IDENTIFIER
+%token <node> LIST
+
+%type <list> statements
+%type <node> statement
+ list_statement
+ expression
%%
statements:
statements ';' statement
{
+ /* only accept this in default parse mode */
+ if (parser_mode != SDB_PARSE_DEFAULT) {
+ sdb_fe_yyerror(&yylloc, scanner,
+ YY_("syntax error, unexpected statement, "
+ "expecting expression"));
+ YYABORT;
+ }
+
+ if ($3) {
+ sdb_llist_append(pt, SDB_OBJ($3));
+ sdb_object_deref(SDB_OBJ($3));
+ }
}
|
statement
{
+ /* only accept this in default parse mode */
+ if (parser_mode != SDB_PARSE_DEFAULT) {
+ sdb_fe_yyerror(&yylloc, scanner,
+ YY_("syntax error, unexpected statement, "
+ "expecting expression"));
+ YYABORT;
+ }
+
+ if ($1) {
+ sdb_llist_append(pt, SDB_OBJ($1));
+ sdb_object_deref(SDB_OBJ($1));
+ }
+ }
+ |
+ expression
+ {
+ /* only accept this in expression parse mode */
+ if (! (parser_mode & SDB_PARSE_EXPR)) {
+ sdb_fe_yyerror(&yylloc, scanner,
+ YY_("syntax error, unexpected expression, "
+ "expecting statement"));
+ YYABORT;
+ }
+
+ if ($1) {
+ sdb_llist_append(pt, SDB_OBJ($1));
+ sdb_object_deref(SDB_OBJ($1));
+ }
}
;
statement:
list_statement
- {
- }
|
/* empty */
+ {
+ $$ = NULL;
+ }
;
list_statement:
LIST
+ {
+ $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL,
+ sdb_conn_node_t));
+ $$->cmd = CONNECTION_LIST;
+ }
+ ;
+
+expression:
+ IDENTIFIER
+ {
+ $$ = SDB_CONN_NODE(sdb_object_create_T(/* name = */ NULL,
+ conn_node_matcher_t));
+ $$->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;
+ }
;
%%