]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: parser: unify subgraphs & simplify even more
authorDavid Lamparter <equinox@opensourcerouting.org>
Sat, 17 Dec 2016 04:25:36 +0000 (05:25 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Mon, 23 Jan 2017 20:52:44 +0000 (21:52 +0100)
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>
lib/command_parse.y
tests/testcli.refout

index 0d3c52a6e010ba77e4f16933cd891b5413eca2dd..db4709172c6a7d8e39d00d4dde0bc219c4dcf064 100644 (file)
 %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
 ;
 
 %%
index 088cbdfec423cb0285524a9edd898c2b0d00e7ed..8b438baee2aa4862c12e00fb5a775227548c1133 100644 (file)
@@ -188,15 +188,11 @@ test# pat c c x
 % [NONE] Unknown command: pat c c x\r
 test# \r
 test# pat d\r
-cmd8 with 2 args.\r
-[00]: pat\r
-[01]: d\r
+% Command incomplete.\r
 test# pat d \r
 bar        baz        foo        \r
 test# pat d \r
-cmd8 with 2 args.\r
-[00]: pat\r
-[01]: d\r
+% Command incomplete.\r
 test# pat d foo 1.2.3.4\r
 cmd8 with 4 args.\r
 [00]: pat\r