diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2016-12-17 05:25:36 +0100 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2017-01-23 21:52:44 +0100 |
commit | 663982cda7188c03472975ef412e57152744eaa5 (patch) | |
tree | ab62d13d6580718260a2e9be3aac47f7becdb371 /lib/command_parse.y | |
parent | lib: parser: keep subgraph pointers on stack (diff) | |
download | frr-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.y | 117 |
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 ; %% |