summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d8dafe6)
raw | patch | inline | side by side (parent: d8dafe6)
author | Sebastian Harl <sh@tokkee.org> | |
Fri, 17 Oct 2014 07:12:08 +0000 (09:12 +0200) | ||
committer | Sebastian 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.
simple expressions.
index 85f278c74dd374d56c24011f06bb6a568f32cd26..4ff4e51bb4ab44f9203ca12b49ab3f8501b64265 100644 (file)
* 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;
* 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)
{
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index ef479efc336ba30e90182ae72557c0892091fc07..40159bf233278664cb5bcdd7fa0941051ea434a2 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
/* 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
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;
}
|
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;
}
|
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;
}
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:
diff --git a/src/frontend/parser.c b/src/frontend/parser.c
index 3184ffc23fb355c3ec5e652f7276292ebac5229c..b0ae01a55bf618ee02f44e3098c290dec273c383 100644 (file)
--- a/src/frontend/parser.c
+++ b/src/frontend/parser.c
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)
enum {
SDB_PARSE_DEFAULT = 0,
SDB_PARSE_COND,
+ SDB_PARSE_EXPR,
};
/* YY_EXTRA data */
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)
* 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