From: Quentin Young Date: Mon, 18 Jul 2016 16:16:36 +0000 (+0000) Subject: lib: Fix some DFA construction bugs X-Git-Tag: frr-3.0-branchpoint~129^2~286 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=4b0abf2434806d5243527b5c75b8bfdcc311edd7;p=matthieu%2Ffrr.git lib: Fix some DFA construction bugs Options get null paths, parser state is properly cleaned up, caller passes start node Signed-off-by: Quentin Young --- diff --git a/lib/cmdtree.c b/lib/cmdtree.c index c7bdf381c7..da647a7ae3 100644 --- a/lib/cmdtree.c +++ b/lib/cmdtree.c @@ -29,7 +29,7 @@ add_node(struct graph_node *parent, struct graph_node *child) int cmp_node(struct graph_node *first, struct graph_node *second) { - return 1; + return 0; } struct graph_node * @@ -44,3 +44,55 @@ new_node(enum graph_node_type type) return node; } + +void +walk_graph(struct graph_node *start, int level) +{ + // print this node + switch (start->type) { + case WORD_GN: + case IPV4_GN: + case IPV4_PREFIX_GN: + case IPV6_GN: + case IPV6_PREFIX_GN: + case VARIABLE_GN: + case RANGE_GN: + fprintf(stderr, "%s", start->text); + break; + case NUMBER_GN: + fprintf(stderr, "%d", start->value); + break; + case SELECTOR_GN: + fprintf(stderr, "<>"); + break; + case OPTION_GN: + fprintf(stderr, "[]"); + break; + case NUL_GN: + fprintf(stderr, "NUL"); + break; + default: + fprintf(stderr, "ERROR"); + } + fprintf(stderr, "[%d] ", vector_active(start->children)); + + if (vector_active(start->children)) + for (unsigned int i = 0; i < vector_active(start->children); i++) { + struct graph_node *r = vector_slot(start->children, i); + if (!r) { + fprintf(stderr, "Child seems null?\n"); + break; + } + else { + if (start->type == OPTION_GN || start->type == SELECTOR_GN) { + fprintf(stderr, "\n"); + for (int i = 0; i < level+1; i++) + fprintf(stderr, "\t"); + } + walk_graph(r, level+1); + } + } + else { + fprintf(stderr, "\n"); + } +} diff --git a/lib/cmdtree.h b/lib/cmdtree.h index e9a10d7ec5..9b512e3bb9 100644 --- a/lib/cmdtree.h +++ b/lib/cmdtree.h @@ -53,3 +53,6 @@ cmp_node(struct graph_node *first, struct graph_node *second); extern struct graph_node * new_node(enum graph_node_type type); + +extern void +walk_graph(struct graph_node *, int); diff --git a/lib/command_parse.y b/lib/command_parse.y index 1f519e27fa..7bdec6dca1 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -8,7 +8,7 @@ extern void yyerror(const char *); #define YYDEBUG 1 %} %code provides { -extern struct graph_node *cmd_parse_format_new(const char *, const char *); +extern struct graph_node *cmd_parse_format_new(const char *, const char *, struct graph_node *); extern void set_buffer_string(const char *); } @@ -19,18 +19,16 @@ extern void set_buffer_string(const char *); } %{ -// last top-level node struct graph_node *startnode, // command root node *currnode, // current node - *tmpnode, // temp node pointer *seqhead; // sequence head -struct graph_node *optnode_start = NULL, // start node for option set - *optnode_end = NULL; // end node for option set +struct graph_node *optnode_start, // start node for option set + *optnode_end; // end node for option set -struct graph_node *selnode_start = NULL, // start node for selector set - *selnode_end = NULL; // end node for selector set +struct graph_node *selnode_start, // start node for selector set + *selnode_end; // end node for selector set %} %token WORD @@ -65,7 +63,12 @@ start: sentence_root sentence_root: WORD { - currnode = new_node(WORD_GN); + $$ = new_node(WORD_GN); + $$->text = strdup(yylval.string); + fprintf(stderr, ">>>>>>>> YYLVAL.STRING: %s\n", yylval.string); + fprintf(stderr, ">>>>>>>> TEXT: %s\n", $$->text); + + currnode = $$; currnode->is_root = 1; add_node(startnode, currnode); }; @@ -98,18 +101,34 @@ cmd_token_seq: placeholder_token: IPV4 -{ $$ = new_node(IPV4_GN); } +{ + $$ = new_node(IPV4_GN); + $$->text = strdup(yylval.string); +} | IPV4_PREFIX -{ $$ = new_node(IPV4_PREFIX_GN); } +{ + $$ = new_node(IPV4_PREFIX_GN); + $$->text = strdup(yylval.string); +} | IPV6 -{ $$ = new_node(IPV6_GN); } +{ + $$ = new_node(IPV6_GN); + $$->text = strdup(yylval.string); +} | IPV6_PREFIX -{ $$ = new_node(IPV6_PREFIX_GN); } +{ + $$ = new_node(IPV6_PREFIX_GN); + $$->text = strdup(yylval.string); +} | VARIABLE -{ $$ = new_node(VARIABLE_GN); } +{ + $$ = new_node(VARIABLE_GN); + $$->text = strdup(yylval.string); +} | RANGE { $$ = new_node(RANGE_GN); + $$->text = strdup(yylval.string); // get the numbers out strsep(&yylval.string, "(-)"); @@ -128,6 +147,8 @@ literal_token: { $$ = new_node(WORD_GN); $$->text = strdup(yylval.string); + fprintf(stderr, ">>>>>>>> YYLVAL.STRING: %s\n", yylval.string); + fprintf(stderr, ">>>>>>>> TEXT: %s\n", $$->text); } | NUMBER { @@ -136,7 +157,7 @@ literal_token: } ; -/* productions */ +/* productions */ selector: '<' selector_part '|' selector_element '>' { @@ -201,7 +222,14 @@ selector_token: /* [option|set] productions */ option: '[' option_part ']' -{ $$ = optnode_start; }; +{ + // add null path + struct graph_node *nullpath = new_node(NUL_GN); + add_node(optnode_start, nullpath); + add_node(nullpath, optnode_end); + + $$ = optnode_start; +}; option_part: option_part '|' option_element @@ -234,30 +262,28 @@ option_token: ; %% -/* -int -main (void) -{ - const char* input = "show [random conf NAME] thing"; - printf("Parsing:\n\t%s\n", input); - return cmd_parse_format_new(input, "description"); -} -*/ + void yyerror(char const *message) { printf("Grammar error: %s\n", message); exit(EXIT_FAILURE); } struct graph_node * -cmd_parse_format_new(const char *string, const char *desc) +cmd_parse_format_new(const char *string, const char *desc, struct graph_node *start) { fprintf(stderr, "parsing: %s\n", string); + /* clear state pointers */ + startnode = currnode = seqhead = NULL; + selnode_start = selnode_end = NULL; + optnode_start = optnode_end = NULL; + + // trace parser yydebug = 1; // make flex read from a string set_buffer_string(string); // initialize the start node of this command dfa - startnode = new_node(NUL_GN); + startnode = start; // parse command into DFA yyparse(); // startnode points to command DFA diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index fd0eec02d6..0cc6896d8e 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -1,5 +1,6 @@ #include "command.h" #include "command_parse.h" +#include "cmdtree.h" #define GRAMMAR_STR "CLI grammar sandbox\n" @@ -21,8 +22,12 @@ DEFUN (grammar_test, strcat(cat, " "); } - cmd_parse_format_new((const char*) cat, "lol"); - + struct graph_node *result = new_node(NUL_GN); + /* cmd_parse_format_new((const char*) cat, "lol", result);*/ + cmd_parse_format_new ("test lol", "lol", result); + cmd_parse_format_new ("test lol", "lol", result); + walk_graph(result, 0); + return CMD_SUCCESS; }