From 92055a924a9fe1f8ae730580904487598ae25da9 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 6 Jul 2016 17:16:55 +0000 Subject: [PATCH] lib: Add parser, lexer, and command tree skeleton Signed-off-by: Quentin Young --- lib/cmdtree.c | 41 +++++++++++++++++++++ lib/command.lex | 35 ++++++++++++++++++ lib/command.y | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 lib/cmdtree.c create mode 100644 lib/command.lex create mode 100644 lib/command.y diff --git a/lib/cmdtree.c b/lib/cmdtree.c new file mode 100644 index 0000000000..921c6d9cc6 --- /dev/null +++ b/lib/cmdtree.c @@ -0,0 +1,41 @@ +#include +#include + +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 index 0000000000..35450cd45f --- /dev/null +++ b/lib/command.lex @@ -0,0 +1,35 @@ +%{ +#include +#include + +#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 index 0000000000..9bc45b5419 --- /dev/null +++ b/lib/command.y @@ -0,0 +1,96 @@ +%{ +#include +#include +#include + +extern int yylex(void); +extern void yyerror(const char *); +%} + +%union{ + int integer; + char *string; +} + +%token WORD +%token IPV4 +%token IPV4_PREFIX +%token IPV6 +%token IPV6_PREFIX +%token VARIABLE +%token RANGE +%token 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");}; */ + + +/* 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); +} -- 2.39.5