These are functionally identical as "fork" tokens.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
{
struct cmd_token *tt = gnn->data;
- if (tt->type < SELECTOR_TKN)
+ if (tt->type < SPECIAL_TKN)
vty_out (vty, " %s", tt->text);
}
if (gn == start)
IPV6_PREFIX_TKN, // IPV6 network prefixes
/* plumbing types */
- SELECTOR_TKN, // marks beginning of selector
- OPTION_TKN, // marks beginning of option
- NUL_TKN, // dummy token
+ FORK_TKN, // marks subgraph beginning
+ JOIN_TKN, // marks subgraph end
START_TKN, // first token in line
END_TKN, // last token in line
+
+ SPECIAL_TKN = FORK_TKN,
};
/* Command attributes */
/**
* Adds all children that are reachable by one parser hop to the given list.
- * NUL_TKN, SELECTOR_TKN, and OPTION_TKN nodes are treated as transparent.
+ * special tokens except END_TKN are treated as transparent.
*
* @param[in] list to add the nexthops to
* @param[in] node to start calculating nexthops from
if (j != stackpos)
continue;
}
- switch (token->type)
+ if (token->type >= SPECIAL_TKN && token->type != END_TKN)
{
- case OPTION_TKN:
- case SELECTOR_TKN:
- case NUL_TKN:
- added += add_nexthops (list, child, stack, stackpos);
- break;
- default:
- if (stack)
- {
- nextstack = XMALLOC (MTYPE_CMD_MATCHSTACK,
- (stackpos + 1) * sizeof(struct graph_node *));
- nextstack[0] = child;
- memcpy(nextstack + 1, stack, stackpos * sizeof(struct graph_node *));
+ added += add_nexthops (list, child, stack, stackpos);
+ }
+ else
+ {
+ if (stack)
+ {
+ nextstack = XMALLOC (MTYPE_CMD_MATCHSTACK,
+ (stackpos + 1) * sizeof(struct graph_node *));
+ nextstack[0] = child;
+ memcpy(nextstack + 1, stack, stackpos * sizeof(struct graph_node *));
- listnode_add (list, nextstack);
- }
- else
- listnode_add (list, child);
- added++;
+ listnode_add (list, nextstack);
+ }
+ else
+ listnode_add (list, child);
+ added++;
}
}
selector: '<' selector_seq_seq '>'
{
$$ = malloc (sizeof (struct subgraph));
- $$->start = new_token_node (ctx, SELECTOR_TKN, NULL, NULL);
- $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL);
+ $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL);
+ $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
for (unsigned int i = 0; i < vector_active ($2->start->to); i++)
{
struct graph_node *sn = vector_slot ($2->start->to, i),
selector: '{' selector_seq_seq '}'
{
$$ = malloc (sizeof (struct subgraph));
- $$->start = new_token_node (ctx, SELECTOR_TKN, NULL, NULL);
- $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL);
+ $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL);
+ $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
graph_add_edge ($$->start, $$->end);
for (unsigned int i = 0; i < vector_active ($2->start->to); i++)
{
{
// make a new option
$$ = malloc (sizeof (struct subgraph));
- $$->start = new_token_node (ctx, OPTION_TKN, NULL, NULL);
- $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL);
+ $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL);
+ $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL);
// add a path through the sequence to the end
graph_add_edge ($$->start, $2->start);
graph_add_edge ($2->end, $$->end);
* cases; ultimately this forks the graph, but the matcher can handle
* this regardless
*/
- case SELECTOR_TKN:
- case OPTION_TKN:
+ case FORK_TKN:
return 0;
/* end nodes are always considered equal, since each node may only
*/
case START_TKN:
case END_TKN:
- case NUL_TKN:
+ case JOIN_TKN:
default:
break;
}
item(IPV6_PREFIX_TKN), // IPV6 network prefixes
/* plumbing types */
- item(SELECTOR_TKN), // marks beginning of selector
- item(OPTION_TKN), // marks beginning of option
- item(NUL_TKN), // dummy token
+ item(FORK_TKN),
+ item(JOIN_TKN),
item(START_TKN), // first token in line
item(END_TKN), // last token in line
{ 0, NULL }
+++ /dev/null
-#ifndef _GRAMMAR_SANDBOX_H
-#define _GRAMMAR_SANDBOX_H
-
-/**
- * Houses functionality for testing shim as well as code that should go into
- * command.h and command.c during integration.
- */
-#include "memory.h"
-
-#define CMD_CR_TEXT "<cr>"
-
-void
-grammar_sandbox_init (void);
-
-/**
- * Types for tokens.
- *
- * The type determines what kind of data the token can match (in the
- * matching use case) or hold (in the argv use case).
- */
-enum cmd_token_type_t
-{
- WORD_TKN, // words
- NUMBER_TKN, // integral numbers
- VARIABLE_TKN, // almost anything
- RANGE_TKN, // integer range
- IPV4_TKN, // IPV4 addresses
- IPV4_PREFIX_TKN, // IPV4 network prefixes
- IPV6_TKN, // IPV6 prefixes
- IPV6_PREFIX_TKN, // IPV6 network prefixes
-
- /* plumbing types */
- SELECTOR_TKN, // marks beginning of selector
- OPTION_TKN, // marks beginning of option
- NUL_TKN, // dummy token
- START_TKN, // first token in line
- END_TKN, // last token in line
-};
-
-/**
- * Token struct.
- */
-struct cmd_token_t
-{
- enum cmd_token_type_t type; // token type
-
- char *text; // token text
- char *desc; // token description
-
- long long value; // for numeric types
- long long min, max; // for ranges
-
- char *arg; // user input that matches this token
-};
-
-#endif /* _GRAMMAR_SANDBOX_H */
for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
{
struct cmd_token *tt = gnn->data;
- if (tt->type < SELECTOR_TKN)
+ if (tt->type < SPECIAL_TKN)
fprintf (stdout, "%s ", tt->text);
}
fprintf (stdout, "\n");