]>
Commit | Line | Data |
---|---|---|
92055a92 | 1 | %{ |
782d9789 | 2 | #include "cmdtree.h" |
92055a92 QY |
3 | |
4 | extern int yylex(void); | |
2a23ca6e QY |
5 | extern void yyerror(const char *); |
6 | extern int cmd_parse_format(const char *, const char *); | |
7 | extern void set_buffer_string(const char *); | |
782d9789 | 8 | |
2a23ca6e | 9 | // compile with debugging facilities |
782d9789 | 10 | #define YYDEBUG 1 |
92055a92 QY |
11 | %} |
12 | ||
13 | %union{ | |
14 | int integer; | |
15 | char *string; | |
782d9789 | 16 | struct graph_node *node; |
92055a92 QY |
17 | } |
18 | ||
782d9789 QY |
19 | %{ |
20 | // last top-level node | |
2a23ca6e QY |
21 | struct graph_node *topnode, // command root node |
22 | *currnode; // current node | |
23 | ||
24 | struct graph_node *optnode_start, // start node for option set | |
25 | *optnode_end, // end node for option set | |
26 | *optnode_el; // start node for an option set element | |
27 | ||
28 | struct graph_node *selnode_start, // start node for selector set | |
29 | *selnode_end, // end node for selector set | |
30 | *selnode_el; // start node for an selector set element | |
782d9789 QY |
31 | %} |
32 | ||
33 | %token <string> WORD | |
34 | %token <string> IPV4 | |
35 | %token <string> IPV4_PREFIX | |
36 | %token <string> IPV6 | |
37 | %token <string> IPV6_PREFIX | |
38 | %token <string> VARIABLE | |
39 | %token <string> RANGE | |
40 | %token <integer> NUMBER | |
41 | ||
42 | %type <node> start | |
43 | %type <node> sentence_root | |
782d9789 QY |
44 | %type <node> literal_token |
45 | %type <node> placeholder_token | |
46 | %type <node> option_token | |
47 | %type <node> selector_token | |
48 | %type <node> option | |
49 | %type <node> selector | |
50 | %type <node> selector_token_seq | |
51 | %type <node> option_token_seq | |
52 | ||
2a23ca6e QY |
53 | %defines "command_parse.h" |
54 | %output "command_parse.c" | |
92055a92 QY |
55 | |
56 | /* grammar proper */ | |
57 | %% | |
58 | ||
782d9789 QY |
59 | start: sentence_root |
60 | cmd_token_seq; | |
92055a92 | 61 | |
2a23ca6e QY |
62 | sentence_root: WORD |
63 | { | |
64 | currnode = new_node(WORD_GN); | |
65 | currnode->is_root = 1; | |
66 | add_node(topnode, currnode); | |
67 | }; | |
92055a92 QY |
68 | |
69 | /* valid top level tokens */ | |
782d9789 QY |
70 | cmd_token: |
71 | placeholder_token | |
2a23ca6e | 72 | { currnode = add_node(currnode, $1); } |
782d9789 | 73 | | literal_token |
2a23ca6e | 74 | { currnode = add_node(currnode, $1); } |
782d9789 | 75 | | selector |
2a23ca6e QY |
76 | { |
77 | add_node(currnode, selnode_start); | |
78 | currnode = selnode_end; | |
79 | } | |
782d9789 | 80 | | option |
2a23ca6e QY |
81 | { |
82 | add_node(currnode, optnode_start); | |
83 | currnode = optnode_end; | |
84 | } | |
782d9789 | 85 | ; |
92055a92 | 86 | |
782d9789 QY |
87 | cmd_token_seq: |
88 | %empty | |
89 | | cmd_token_seq cmd_token | |
90 | ; | |
91 | ||
92 | placeholder_token: | |
93 | IPV4 {$$ = new_node(IPV4_GN);} | |
94 | | IPV4_PREFIX {$$ = new_node(IPV4_PREFIX_GN);} | |
95 | | IPV6 {$$ = new_node(IPV6_GN);} | |
96 | | IPV6_PREFIX {$$ = new_node(IPV6_PREFIX_GN);} | |
97 | | VARIABLE {$$ = new_node(VARIABLE_GN);} | |
98 | | RANGE {$$ = new_node(RANGE_GN);} | |
99 | ; | |
100 | ||
101 | literal_token: | |
102 | WORD {$$ = new_node(WORD_GN);} | |
103 | | NUMBER {$$ = new_node(NUMBER_GN);} | |
104 | ; | |
92055a92 QY |
105 | |
106 | /* <selector|token> productions */ | |
782d9789 QY |
107 | selector: |
108 | '<' selector_part '|' | |
2a23ca6e QY |
109 | selector_element '>' |
110 | { | |
111 | $$ = new_node(SELECTOR_GN); | |
112 | // attach subtree here | |
113 | }; | |
782d9789 QY |
114 | |
115 | selector_part: | |
2a23ca6e | 116 | selector_part '|' selector_element |
782d9789 QY |
117 | | selector_element |
118 | ; | |
119 | ||
120 | selector_element: | |
121 | WORD selector_token_seq; | |
122 | ||
123 | selector_token_seq: | |
2a23ca6e QY |
124 | %empty {$$ = NULL;} |
125 | | selector_token_seq selector_token | |
126 | { | |
127 | currnode = add_node(currnode, $2); | |
128 | } | |
782d9789 QY |
129 | ; |
130 | ||
131 | selector_token: | |
132 | literal_token | |
133 | | placeholder_token | |
134 | | option | |
135 | ; | |
92055a92 QY |
136 | |
137 | /* [option|set] productions */ | |
2a23ca6e QY |
138 | option: '[' option_part ']' |
139 | { | |
140 | $$ = new_node(OPTION_GN); | |
141 | // attach subtree here | |
142 | }; | |
782d9789 QY |
143 | |
144 | option_part: | |
145 | option_part '|' option_token_seq | |
146 | | option_token_seq | |
147 | ; | |
148 | ||
149 | option_token_seq: | |
2a23ca6e QY |
150 | option_token_seq option_token |
151 | | option_token | |
152 | { | |
153 | printf("Matched singular option token in sequence, type: %d\n", $1->type); | |
154 | } | |
782d9789 QY |
155 | ; |
156 | ||
157 | option_token: | |
158 | literal_token | |
2a23ca6e QY |
159 | { |
160 | // optnode_el points to root of option element | |
161 | if (optnode_el == NULL) { | |
162 | optnode_el = $1; | |
163 | currnode = $1; | |
164 | } | |
165 | else | |
166 | add_node(currnode, $1); | |
167 | } | |
782d9789 | 168 | | placeholder_token |
2a23ca6e QY |
169 | { |
170 | // optnode_el points to root of option element | |
171 | if (optnode_el == NULL) { | |
172 | optnode_el = $1; | |
173 | currnode = $1; | |
174 | } | |
175 | else | |
176 | add_node(currnode, $1); | |
177 | } | |
782d9789 QY |
178 | ; |
179 | ||
92055a92 QY |
180 | %% |
181 | ||
182 | int | |
183 | main (void) | |
184 | { | |
782d9789 QY |
185 | yydebug = 1; |
186 | const char* input = "show [random conf NAME] thing"; | |
187 | printf("Parsing:\n\t%s\n", input); | |
188 | return cmd_parse_format(input, "description"); | |
92055a92 QY |
189 | } |
190 | ||
191 | void yyerror(char const *message) { | |
192 | printf("Grammar error: %s\n", message); | |
193 | exit(EXIT_FAILURE); | |
194 | } | |
782d9789 QY |
195 | |
196 | int | |
197 | cmd_parse_format(const char *string, const char *desc) | |
198 | { | |
2a23ca6e QY |
199 | // make flex read from a string |
200 | set_buffer_string(string); | |
201 | // initialize the start node of this command dfa | |
202 | topnode = new_node(NUL_GN); | |
203 | // parse command into DFA | |
782d9789 | 204 | yyparse(); |
2a23ca6e | 205 | // topnode points to command DFA |
782d9789 QY |
206 | return 0; |
207 | } |