Code

frontend: Added sdb_fe_parse_expr().
authorSebastian Harl <sh@tokkee.org>
Fri, 17 Oct 2014 07:12:08 +0000 (09:12 +0200)
committerSebastian Harl <sh@tokkee.org>
Fri, 17 Oct 2014 07:12:08 +0000 (09:12 +0200)
This function enables a special new parser mode in which it only accepts
simple expressions.

src/frontend/connection-private.h
src/frontend/grammar.y
src/frontend/parser.c
src/include/frontend/parser.h
src/include/frontend/proto.h

index 85f278c74dd374d56c24011f06bb6a568f32cd26..4ff4e51bb4ab44f9203ca12b49ab3f8501b64265 100644 (file)
@@ -81,6 +81,12 @@ struct sdb_conn {
  * node types
  */
 
+typedef struct {
+       sdb_conn_node_t super;
+       sdb_store_expr_t *expr;
+} conn_expr_t;
+#define CONN_EXPR(obj) ((conn_expr_t *)(obj))
+
 typedef struct {
        sdb_conn_node_t super;
        sdb_store_matcher_t *matcher;
@@ -122,6 +128,12 @@ typedef struct {
  * type helper functions
  */
 
+static void __attribute__((unused))
+conn_expr_destroy(sdb_object_t *obj)
+{
+       sdb_object_deref(SDB_OBJ(CONN_EXPR(obj)->expr));
+} /* conn_expr_destroy */
+
 static void __attribute__((unused))
 conn_matcher_destroy(sdb_object_t *obj)
 {
index ef479efc336ba30e90182ae72557c0892091fc07..40159bf233278664cb5bcdd7fa0941051ea434a2 100644 (file)
@@ -56,6 +56,12 @@ 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
 
+#define MODE_TO_STRING(m) \
+       (((m) == SDB_PARSE_DEFAULT) ? "statement" \
+               : ((m) == SDB_PARSE_COND) ? "condition" \
+               : ((m) == SDB_PARSE_EXPR) ? "expression" \
+               : "UNKNOWN")
+
 %}
 
 %pure-parser
@@ -148,11 +154,13 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 statements:
        statements ';' statement
                {
-                       /* only accept this in default parse mode */
+                       /* only accepted in default parse mode */
                        if (parser_mode != SDB_PARSE_DEFAULT) {
-                               sdb_fe_yyerror(&yylloc, scanner,
+                               char errmsg[1024];
+                               snprintf(errmsg, sizeof(errmsg),
                                                YY_("syntax error, unexpected statement, "
-                                                       "expecting condition"));
+                                                       "expecting %s"), MODE_TO_STRING(parser_mode));
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
                                sdb_object_deref(SDB_OBJ($3));
                                YYABORT;
                        }
@@ -165,11 +173,13 @@ statements:
        |
        statement
                {
-                       /* only accept this in default parse mode */
+                       /* only accepted in default parse mode */
                        if (parser_mode != SDB_PARSE_DEFAULT) {
-                               sdb_fe_yyerror(&yylloc, scanner,
+                               char errmsg[1024];
+                               snprintf(errmsg, sizeof(errmsg),
                                                YY_("syntax error, unexpected statement, "
-                                                       "expecting condition"));
+                                                       "expecting %s"), MODE_TO_STRING(parser_mode));
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
                                sdb_object_deref(SDB_OBJ($1));
                                YYABORT;
                        }
@@ -182,11 +192,13 @@ statements:
        |
        condition
                {
-                       /* only accept this in condition parse mode */
+                       /* only accepted in condition parse mode */
                        if (! (parser_mode & SDB_PARSE_COND)) {
-                               sdb_fe_yyerror(&yylloc, scanner,
+                               char errmsg[1024];
+                               snprintf(errmsg, sizeof(errmsg),
                                                YY_("syntax error, unexpected condition, "
-                                                       "expecting statement"));
+                                                       "expecting %s"), MODE_TO_STRING(parser_mode));
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
                                sdb_object_deref(SDB_OBJ($1));
                                YYABORT;
                        }
@@ -196,6 +208,31 @@ statements:
                                sdb_object_deref(SDB_OBJ($1));
                        }
                }
+       |
+       expression
+               {
+                       /* only accepted in expression parse mode */
+                       if (! (parser_mode & SDB_PARSE_EXPR)) {
+                               char errmsg[1024];
+                               snprintf(errmsg, sizeof(errmsg),
+                                               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;
+                       }
+
+                       if ($1) {
+                               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;
+                               CONN_EXPR($$)->expr = $1;
+
+                               sdb_llist_append(pt, SDB_OBJ(n));
+                               sdb_object_deref(SDB_OBJ(n));
+                       }
+               }
        ;
 
 statement:
index 3184ffc23fb355c3ec5e652f7276292ebac5229c..b0ae01a55bf618ee02f44e3098c290dec273c383 100644 (file)
@@ -126,5 +126,44 @@ sdb_fe_parse_matcher(const char *cond, int len)
        return m;
 } /* sdb_fe_parse_matcher */
 
+sdb_store_expr_t *
+sdb_fe_parse_expr(const char *expr, int len)
+{
+       sdb_fe_yyscan_t scanner;
+       sdb_fe_yyextra_t yyextra;
+
+       sdb_conn_node_t *node;
+       sdb_store_expr_t *e;
+
+       int yyres;
+
+       if (scanner_init(expr, len, &scanner, &yyextra))
+               return NULL;
+
+       yyextra.mode = SDB_PARSE_EXPR;
+
+       yyres = sdb_fe_yyparse(scanner);
+       sdb_fe_scanner_destroy(scanner);
+
+       if (yyres) {
+               sdb_llist_destroy(yyextra.parsetree);
+               return NULL;
+       }
+
+       node = SDB_CONN_NODE(sdb_llist_get(yyextra.parsetree, 0));
+       if (! node)
+               return NULL;
+
+       if (node->cmd == CONNECTION_EXPR)
+               e = CONN_EXPR(node)->expr;
+       else
+               e = NULL;
+
+       CONN_EXPR(node)->expr = NULL;
+       sdb_llist_destroy(yyextra.parsetree);
+       sdb_object_deref(SDB_OBJ(node));
+       return e;
+} /* sdb_fe_parse_expr */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
 
index c5fb4ab1207f399d5429923faa3c8181a39b66d2..d2dfb01f723985d54cf03866740db3479bbec448 100644 (file)
@@ -39,6 +39,7 @@ extern "C" {
 enum {
        SDB_PARSE_DEFAULT = 0,
        SDB_PARSE_COND,
+       SDB_PARSE_EXPR,
 };
 
 /* YY_EXTRA data */
@@ -65,6 +66,9 @@ sdb_fe_yyparse(sdb_fe_yyscan_t scanner);
 sdb_store_matcher_t *
 sdb_fe_parse_matcher(const char *cond, int len);
 
+sdb_store_expr_t *
+sdb_fe_parse_expr(const char *expr, int len);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 0577550b57f25c8814f7fb399e69b4bd623180b5..3819e3f07ce953309c73265a8f81c82a9fd5e924 100644 (file)
@@ -254,6 +254,12 @@ typedef enum {
         * A parsed matcher. Only used internally.
         */
        CONNECTION_MATCHER = 100,
+
+       /*
+        * CONNECTION_EXPR:
+        * A parsed expression. Only used internally.
+        */
+       CONNECTION_EXPR,
 } sdb_conn_state_t;
 
 #ifdef __cplusplus