]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Add parser, lexer, and command tree skeleton
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 6 Jul 2016 17:16:55 +0000 (17:16 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 12 Jul 2016 15:05:05 +0000 (15:05 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/cmdtree.c [new file with mode: 0644]
lib/command.lex [new file with mode: 0644]
lib/command.y [new file with mode: 0644]

diff --git a/lib/cmdtree.c b/lib/cmdtree.c
new file mode 100644 (file)
index 0000000..921c6d9
--- /dev/null
@@ -0,0 +1,41 @@
+#include <command.h>
+#include <vector.h>
+
+enum tree_node_type
+{
+  WORD_TN,
+  IPV4_TN,
+  IPV4_PREFIX_TN,
+  IPV6_TN,
+  IPV6_PREFIX_TN,
+  VARIABLE_TN,
+  RANGE_TN,
+  NUMBER_TN,
+  SELECTOR_TN,
+  OPTION_TN
+}
+
+struct tree_node
+{
+  enum tree_node_type type;
+  vector children;
+  int leaf;
+  (int) (*func(struct cmd_info *, struct vty *, int, const char *[]));
+}
+
+void add_node(struct tree_node *parent, struct tree_node *child)
+{
+
+}
+
+// checks nodes for equivalence; definition of equivalence depends
+// on node type (WORD_TN strcmps words, etc)
+int cmp_node(struct tree_node *first, struct tree_node *second)
+{
+  
+}
+
+int merge_tree(struct tree_node *first, struct tree_node *second)
+{
+
+}
diff --git a/lib/command.lex b/lib/command.lex
new file mode 100644 (file)
index 0000000..35450cd
--- /dev/null
@@ -0,0 +1,35 @@
+%{
+#include <string.h>
+#include <stdlib.h>
+
+#include "command.tab.h"
+%}
+
+WORD            [a-z][-_a-z0-9]+
+IPV4            A\.B\.C\.D
+IPV4_PREFIX     A\.B\.C\.D\/M
+IPV6            X:X::X:X
+IPV6_PREFIX     X:X::X:X\/M
+VARIABLE        [A-Z][A-Z_]+
+NUMBER          [0-9]{1,20}
+RANGE           \({NUMBER}\-{NUMBER}\)
+
+/* yytext shall be a pointer */
+%pointer
+%option noyywrap
+
+%%
+"<"             return '<';
+">"             return '>';
+
+[ /t]           /* ignore whitespace */;
+{WORD}          {yylval.string = strdup(yytext); return WORD;}
+{IPV4}          {yylval.string = strdup(yytext); return IPV4;}
+{IPV4_PREFIX}   {yylval.string = strdup(yytext); return IPV4_PREFIX;}
+{IPV6}          {yylval.string = strdup(yytext); return IPV6;}
+{IPV6_PREFIX}   {yylval.string = strdup(yytext); return IPV6_PREFIX;}
+{VARIABLE}      {yylval.string = strdup(yytext); return VARIABLE;}
+{NUMBER}        {yylval.integer = atoi(yytext); return NUMBER;}
+{RANGE}         {yylval.string = strdup(yytext); return RANGE;}
+.               {return yytext[0];}
+%%
diff --git a/lib/command.y b/lib/command.y
new file mode 100644 (file)
index 0000000..9bc45b5
--- /dev/null
@@ -0,0 +1,96 @@
+%{
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+extern int yylex(void);
+extern void yyerror(const char *);
+%}
+
+%union{
+  int integer;
+  char *string;
+}
+
+%token <string>     WORD
+%token <string>     IPV4
+%token <string>     IPV4_PREFIX
+%token <string>     IPV6
+%token <string>     IPV6_PREFIX
+%token <string>     VARIABLE
+%token <string>     RANGE
+%token <integer>    NUMBER
+
+/* grammar proper */
+%%
+
+start: sentence_root                    {printf("Matched sentence root\n");}
+       cmd_token_seq                    {printf("Matched sentence\n");};
+
+sentence_root: WORD                     {printf("Sentence root: %s\n", $1);};
+
+/* valid top level tokens */
+cmd_token: placeholder_token
+         | literal_token
+         | selector
+         | option
+         ;
+cmd_token_seq: /* empty */
+             | cmd_token_seq cmd_token;
+
+placeholder_token: IPV4                 {printf("Matched placeholder\n");}
+                 | IPV4_PREFIX          {printf("Matched placeholder\n");}
+                 | IPV6                 {printf("Matched placeholder\n");}
+                 | IPV6_PREFIX          {printf("Matched placeholder\n");}
+                 | VARIABLE             {printf("Matched placeholder\n");}
+                 | RANGE                {printf("Matched placeholder\n");}
+
+literal_token: WORD
+             | NUMBER
+             ;
+/* range: '(' NUMBER '-' NUMBER ')'        {printf("Matched range\n");}; */
+
+
+/* <selector|token> productions */
+selector: '<' selector_part '|'
+              selector_element '>'      {printf("Matched selector\n");};
+selector_part: selector_part '|'
+               selector_element
+             | selector_element
+                                        {printf("Matched selector part\n");};
+selector_element: WORD
+                  selector_token_seq
+selector_token_seq: /* empty */
+                  | selector_token_seq
+                    selector_token
+                  ;
+selector_token: literal_token
+              | placeholder_token
+              | option
+              ;
+
+/* [option|set] productions */
+option: '[' option_part ']'             {printf("Matched option\n");};
+option_part: option_part '|'
+             option_element_seq
+           | option_element_seq
+           ;
+option_element_seq: option_token
+                  | option_element_seq
+                    option_token
+                  ;
+option_token: literal_token
+            | placeholder_token
+            ;
+%%
+
+int
+main (void)
+{
+  return yyparse ();
+}
+
+void yyerror(char const *message) {
+  printf("Grammar error: %s\n", message);
+  exit(EXIT_FAILURE);
+}