summaryrefslogtreecommitdiffstats
path: root/lib/command_parse.y
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-12-17 05:25:36 +0100
committerDavid Lamparter <equinox@opensourcerouting.org>2017-01-23 21:52:44 +0100
commit663982cda7188c03472975ef412e57152744eaa5 (patch)
treeab62d13d6580718260a2e9be3aac47f7becdb371 /lib/command_parse.y
parentlib: parser: keep subgraph pointers on stack (diff)
downloadfrr-663982cda7188c03472975ef412e57152744eaa5.tar.xz
frr-663982cda7188c03472975ef412e57152744eaa5.zip
lib: parser: unify subgraphs & simplify even more
This cuts a large piece of complexity from the parser by making the sequences between | the same, no matter whether it's <> () or []. This causes some changes in behaviour: - [foo|bar] is now accepted - <foo|[bar]> is now accepted (yes it's stupid) - {a|b} is now means "at least one of these, in any order"; to allow zero use [{a|b}] instead. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/command_parse.y')
-rw-r--r--lib/command_parse.y117
1 files changed, 24 insertions, 93 deletions
diff --git a/lib/command_parse.y b/lib/command_parse.y
index 0d3c52a6e..db4709172 100644
--- a/lib/command_parse.y
+++ b/lib/command_parse.y
@@ -99,14 +99,10 @@
%type <node> literal_token
%type <node> placeholder_token
%type <node> simple_token
-%type <subgraph> option
-%type <subgraph> option_token
-%type <subgraph> option_token_seq
%type <subgraph> selector
%type <subgraph> selector_token
%type <subgraph> selector_token_seq
%type <subgraph> selector_seq_seq
-%type <subgraph> compound_token
%code {
@@ -202,7 +198,7 @@ cmd_token:
if ((ctx->currnode = add_edge_dedup (ctx->currnode, $1)) != $1)
graph_delete_node (ctx->graph, $1);
}
-| compound_token
+| selector
{
graph_add_edge (ctx->currnode, $1.start);
ctx->currnode = $1.end;
@@ -214,11 +210,6 @@ simple_token:
| placeholder_token
;
-compound_token:
- selector
-| option
-;
-
literal_token: WORD
{
$$ = new_token_node (ctx, WORD_TKN, strdup($1), doc_next(ctx));
@@ -272,126 +263,66 @@ placeholder_token:
/* <selector|set> productions */
selector: '<' selector_seq_seq '>'
{
- $$.start = new_token_node (ctx, FORK_TKN, NULL, NULL);
- $$.end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
- ((struct cmd_token *)$$.start->data)->forkjoin = $$.end;
- ((struct cmd_token *)$$.end->data)->forkjoin = $$.start;
- for (unsigned int i = 0; i < vector_active ($2.start->to); i++)
- {
- struct graph_node *sn = vector_slot ($2.start->to, i),
- *en = vector_slot ($2.end->from, i);
- graph_add_edge ($$.start, sn);
- graph_add_edge (en, $$.end);
- }
- graph_delete_node (ctx->graph, $2.start);
- graph_delete_node (ctx->graph, $2.end);
+ $$ = $2;
};
selector_seq_seq:
selector_seq_seq '|' selector_token_seq
{
- $$.start = graph_new_node (ctx->graph, NULL, NULL);
- $$.end = graph_new_node (ctx->graph, NULL, NULL);
-
- // link in last sequence
+ $$ = $1;
graph_add_edge ($$.start, $3.start);
graph_add_edge ($3.end, $$.end);
-
- for (unsigned int i = 0; i < vector_active ($1.start->to); i++)
- {
- struct graph_node *sn = vector_slot ($1.start->to, i),
- *en = vector_slot ($1.end->from, i);
- graph_add_edge ($$.start, sn);
- graph_add_edge (en, $$.end);
- }
- graph_delete_node (ctx->graph, $1.start);
- graph_delete_node (ctx->graph, $1.end);
}
-| selector_token_seq '|' selector_token_seq
+| selector_token_seq
{
- $$.start = graph_new_node (ctx->graph, NULL, NULL);
- $$.end = graph_new_node (ctx->graph, NULL, NULL);
+ $$.start = new_token_node (ctx, FORK_TKN, NULL, NULL);
+ $$.end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
+ ((struct cmd_token *)$$.start->data)->forkjoin = $$.end;
+ ((struct cmd_token *)$$.end->data)->forkjoin = $$.start;
+
graph_add_edge ($$.start, $1.start);
graph_add_edge ($1.end, $$.end);
- graph_add_edge ($$.start, $3.start);
- graph_add_edge ($3.end, $$.end);
}
;
/* {keyword} productions */
selector: '{' selector_seq_seq '}'
{
- $$.start = new_token_node (ctx, FORK_TKN, NULL, NULL);
- $$.end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
- ((struct cmd_token *)$$.start->data)->forkjoin = $$.end;
- ((struct cmd_token *)$$.end->data)->forkjoin = $$.start;
- graph_add_edge ($$.start, $$.end);
- for (unsigned int i = 0; i < vector_active ($2.start->to); i++)
- {
- struct graph_node *sn = vector_slot ($2.start->to, i),
- *en = vector_slot ($2.end->from, i);
- graph_add_edge ($$.start, sn);
- graph_add_edge (en, $$.start);
- }
- graph_delete_node (ctx->graph, $2.start);
- graph_delete_node (ctx->graph, $2.end);
+ $$ = $2;
+ graph_add_edge ($$.end, $$.start);
+ /* there is intentionally no start->end link, for two reasons:
+ * 1) this allows "at least 1 of" semantics, which are otherwise impossible
+ * 2) this would add a start->end->start loop in the graph that the current
+ * loop-avoidal fails to handle
+ * just use [{a|b}] if neccessary, that will work perfectly fine, and reason
+ * #1 is good enough to keep it this way. */
};
-selector_token_seq:
- simple_token
-{
- $$.start = $$.end = $1;
-}
-| selector_token_seq selector_token
-{
- graph_add_edge ($1.end, $2.start);
- $$.start = $1.start;
- $$.end = $2.end;
-}
-;
-
selector_token:
simple_token
{
$$.start = $$.end = $1;
}
-| option
| selector
;
-/* [option] productions */
-option: '[' option_token_seq ']'
-{
- // make a new option
- $$.start = new_token_node (ctx, FORK_TKN, NULL, NULL);
- $$.end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
- ((struct cmd_token *)$$.start->data)->forkjoin = $$.end;
- ((struct cmd_token *)$$.end->data)->forkjoin = $$.start;
- // add a path through the sequence to the end
- graph_add_edge ($$.start, $2.start);
- graph_add_edge ($2.end, $$.end);
- // add a path directly from the start to the end
- graph_add_edge ($$.start, $$.end);
-}
-;
-
-option_token_seq:
- option_token
-| option_token_seq option_token
+selector_token_seq:
+ selector_token_seq selector_token
{
graph_add_edge ($1.end, $2.start);
$$.start = $1.start;
$$.end = $2.end;
}
+| selector_token
;
-option_token:
- simple_token
+/* [option] productions */
+selector: '[' selector_seq_seq ']'
{
- $$.start = $$.end = $1;
+ $$ = $2;
+ graph_add_edge ($$.start, $$.end);
}
-| compound_token
;
%%