diff options
| -rw-r--r-- | lib/cmdtree.c | 10 | ||||
| -rw-r--r-- | lib/cmdtree.h | 9 | ||||
| -rw-r--r-- | lib/command_lex.l (renamed from lib/command.lex) | 17 | ||||
| -rw-r--r-- | lib/command_parse.y (renamed from lib/command.y) | 109 | 
4 files changed, 99 insertions, 46 deletions
diff --git a/lib/cmdtree.c b/lib/cmdtree.c index 5bb76cce3a..c7bdf381c7 100644 --- a/lib/cmdtree.c +++ b/lib/cmdtree.c @@ -6,18 +6,19 @@   * @author Quentin Young <qlyoung@cumulusnetworks.com>   */ -#include "memory.h" +#include <zebra.h>  #include "cmdtree.h" +#include "memory.h"  struct graph_node *  add_node(struct graph_node *parent, struct graph_node *child)  { -  int index; +  unsigned int index;    struct graph_node *p_child;    for (index = 0; index < vector_active(parent->children); index++)    { -    *p_child = vector_slot(parent->children, index); +    p_child = vector_slot(parent->children, index);      if (cmp_node(child, p_child))        return p_child;    } @@ -28,12 +29,13 @@ add_node(struct graph_node *parent, struct graph_node *child)  int  cmp_node(struct graph_node *first, struct graph_node *second)  { +  return 1;  }  struct graph_node *  new_node(enum graph_node_type type)  { -  struct graph_node *node = XMALLOC(MTYPE_TMP, sizeof(graph_node)); +  struct graph_node *node = malloc(sizeof(struct graph_node));    node->type = type;    node->children = vector_init(VECTOR_MIN_SIZE);    node->is_leaf = 0; diff --git a/lib/cmdtree.h b/lib/cmdtree.h index 77d2e0aa34..cdcf347006 100644 --- a/lib/cmdtree.h +++ b/lib/cmdtree.h @@ -1,3 +1,4 @@ +#include "vty.h"  #include "vector.h"  enum graph_node_type @@ -20,14 +21,14 @@ struct graph_node    enum graph_node_type type;    vector children;    int is_leaf, is_root; -  // int (*func(struct cmd_info *, struct vty *, int, const char *[])); +  int (*func)(struct vty *, int, const char *[]);  };  /*   * Adds a child to a node. If the node already has the exact same   * child, nothing is done.   */ -struct graph_node * +extern struct graph_node *  add_node(struct graph_node *, struct graph_node *);  /* @@ -36,8 +37,8 @@ add_node(struct graph_node *, struct graph_node *);   * node type.   * @return 0 if equal, nonzero otherwise.   */ -int +extern int  cmp_node(struct graph_node *first, struct graph_node *second); -struct graph_node * +extern struct graph_node *  new_node(enum graph_node_type type); diff --git a/lib/command.lex b/lib/command_lex.l index ae97265ff7..45f8f8e636 100644 --- a/lib/command.lex +++ b/lib/command_lex.l @@ -1,8 +1,7 @@  %{ -#include <string.h> -#include <stdlib.h> +#include "command_parse.h" -#include "command.h" +extern void set_buffer_string(const char *);  %}  WORD            [a-z][-_a-z0-9]+ @@ -17,11 +16,11 @@ RANGE           \({NUMBER}\-{NUMBER}\)  /* yytext shall be a pointer */  %pointer  %option noyywrap +%option nounput +%option noinput +%option outfile="command_lex.c"  %% -"<"             return '<'; -">"             return '>'; -  [ /t]           /* ignore whitespace */;  {WORD}          {yylval.string = strdup(yytext); return WORD;}  {IPV4}          {yylval.string = strdup(yytext); return IPV4;} @@ -33,3 +32,9 @@ RANGE           \({NUMBER}\-{NUMBER}\)  {RANGE}         {yylval.string = strdup(yytext); return RANGE;}  .               {return yytext[0];}  %% + +void +set_buffer_string(const char *string) +{ +  yy_scan_string(string); +} diff --git a/lib/command.y b/lib/command_parse.y index 1394ef4214..e7efb0d5a8 100644 --- a/lib/command.y +++ b/lib/command_parse.y @@ -1,13 +1,12 @@  %{ -#include <string.h> -#include <stdlib.h> -#include <stdio.h>  #include "cmdtree.h"  extern int yylex(void); -void yyerror(const char *); +extern void yyerror(const char *); +extern int cmd_parse_format(const char *, const char *); +extern void set_buffer_string(const char *); -// turn on debug +// compile with debugging facilities  #define YYDEBUG 1  %} @@ -19,10 +18,16 @@ void yyerror(const char *);  %{  // last top-level node -struct graph_node *topnode, -//  -                  *optnode, -                  *selnode; +struct graph_node *topnode,         // command root node +                  *currnode;        // current node + +struct graph_node *optnode_start,   // start node for option set +                  *optnode_end,     // end node for option set +                  *optnode_el;      // start node for an option set element + +struct graph_node *selnode_start,   // start node for selector set +                  *selnode_end,     // end node for selector set +                  *selnode_el;      // start node for an selector set element  %}  %token <string>  WORD @@ -36,7 +41,6 @@ struct graph_node *topnode,  %type <node> start  %type <node> sentence_root -%type <node> cmd_token  %type <node> literal_token  %type <node> placeholder_token  %type <node> option_token @@ -46,8 +50,8 @@ struct graph_node *topnode,  %type <node> selector_token_seq  %type <node> option_token_seq -%output "command.c" -%defines +%defines "command_parse.h" +%output "command_parse.c"  /* grammar proper */  %% @@ -55,17 +59,29 @@ struct graph_node *topnode,  start: sentence_root         cmd_token_seq; -sentence_root: WORD                     { -                                          currnode = new_node(WORD_GN); -                                          currnode->is_root = 1; -                                        }; +sentence_root: WORD +  { +    currnode = new_node(WORD_GN); +    currnode->is_root = 1; +    add_node(topnode, currnode); +  };  /* valid top level tokens */  cmd_token:    placeholder_token +  { currnode = add_node(currnode, $1); }  | literal_token +  { currnode = add_node(currnode, $1); }  | selector +  { +    add_node(currnode, selnode_start); +    currnode = selnode_end; +  }  | option +  { +    add_node(currnode, optnode_start); +    currnode = optnode_end; +  }  ;  cmd_token_seq: @@ -90,13 +106,14 @@ literal_token:  /* <selector|token> productions */  selector:    '<' selector_part '|' -      selector_element '>'              { -                                        //$$ = new_node(SELECTOR_GN); -                                        //add_node($$, $4); -                                        }; +      selector_element '>' +{ +  $$ = new_node(SELECTOR_GN); +  // attach subtree here +};  selector_part: -  selector_part '|' selector_element     +  selector_part '|' selector_element  | selector_element  ; @@ -104,11 +121,11 @@ selector_element:    WORD selector_token_seq;  selector_token_seq: -  %empty -| selector_token_seq selector_token     { -                                        //add_node(currnode, $2); -                                        //currnode = $2; -                                        } +  %empty                                {$$ = NULL;} +| selector_token_seq selector_token +{ +  currnode = add_node(currnode, $2); +}  ;  selector_token: @@ -118,7 +135,11 @@ selector_token:  ;  /* [option|set] productions */ -option: '[' option_part ']'; +option: '[' option_part ']' +{ +  $$ = new_node(OPTION_GN); +  // attach subtree here +};  option_part:    option_part '|' option_token_seq @@ -126,13 +147,34 @@ option_part:  ;  option_token_seq: -  option_token -| option_token_seq option_token +  option_token_seq option_token +| option_token +{ +  printf("Matched singular option token in sequence, type: %d\n", $1->type); +}  ;  option_token:    literal_token +{ +  // optnode_el points to root of option element +  if (optnode_el == NULL) { +    optnode_el = $1; +    currnode = $1; +  } +  else +    add_node(currnode, $1); +}  | placeholder_token +{ +  // optnode_el points to root of option element +  if (optnode_el == NULL) { +    optnode_el = $1; +    currnode = $1; +  } +  else +    add_node(currnode, $1); +}  ;  %% @@ -154,9 +196,12 @@ void yyerror(char const *message) {  int  cmd_parse_format(const char *string, const char *desc)  { -  yy_scan_string(string); +  // make flex read from a string +  set_buffer_string(string); +  // initialize the start node of this command dfa +  topnode = new_node(NUL_GN); +  // parse command into DFA    yyparse(); +  // topnode points to command DFA    return 0;  } - -  | 
