- started to build the expresion & acion tree/list
[sip-router] / cfg.y
1 /*
2  * $Id$
3  *
4  *  cfg grammar
5  */
6
7 %{
8
9 #include "route_struct.h"
10
11 %}
12
13 %union {
14         int intval;
15         char* strval;
16         struct expr* expr;
17         struct action* action;
18 }
19
20 /* terminals */
21
22
23 /* keywors */
24 %token FORWARD
25 %token SEND
26 %token DROP
27 %token LOG
28 %token ERROR
29 %token ROUTE
30 %token METHOD
31 %token URI
32 %token SRCIP
33 %token DSTIP
34
35 /* config vars. */
36 %token DEBUG
37 %token FORK
38 %token LOGSTDERROR
39 %token LISTEN
40 %token DNS
41 %token REV_DNS
42
43
44 /* operators */
45 %nonassoc EQUAL
46 %nonassoc EQUAL_T
47 %nonassoc MATCH
48 %left NOT
49 %left AND
50 %left OR
51
52 /* values */
53 %token <intval> NUMBER
54 %token <strval> ID
55 %token <strval> STRING
56
57 /* other */
58 %token COMMA
59 %token SEMICOLON
60 %token RPAREN
61 %token LPAREN
62 %token LBRACE
63 %token RBRACE
64 %token LBRACK
65 %token RBRACK
66 %token SLASH
67 %token DOT
68 %token CR
69
70
71 /*non-terminals */
72 %type <expr> exp, condition,  exp_elem
73 %type <action> action, actions, cmd
74
75
76
77 %%
78
79
80 cfg:    statements
81         ;
82
83 statements:     statements statement {printf("got <> <>\n");}
84                 | statement {printf("got a statement<>\n"); }
85                 | statements error { yyerror(""); }
86         ;
87
88 statement:      assign_stm CR
89                 | route_stm CR
90                 | CR    /* null statement*/
91         ;
92
93 assign_stm:     DEBUG EQUAL NUMBER 
94                 | DEBUG EQUAL error  { yyerror("number  expected"); }
95                 | FORK  EQUAL NUMBER
96                 | FORK  EQUAL error  { yyerror("boolean value expected"); }
97                 | LOGSTDERROR EQUAL NUMBER 
98                 | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
99                 | DNS EQUAL NUMBER
100                 | DNS EQUAL error { yyerror("boolean value expected"); }
101                 | REV_DNS EQUAL NUMBER 
102                 | REV_DNS EQUAL error { yyerror("boolean value expected"); }
103                 | LISTEN EQUAL ipv4 
104                 | LISTEN EQUAL ID 
105                 | LISTEN EQUAL STRING
106                 | LISTEN EQUAL  error { yyerror("ip address or hostname"
107                                                 "expected"); }
108                 | error EQUAL { yyerror("unknown config variable"); }
109         ;
110
111
112 ipv4:   NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
113         ;
114
115 route_stm:      ROUTE LBRACE rules RBRACE 
116                 | ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE
117                 | ROUTE error { yyerror("invalid  route  statement"); }
118         ;
119
120 rules:  rules rule
121         | rule
122         | rules error { yyerror("invalid rule"); }
123          ;
124
125 rule:   condition       actions CR
126         | CR  /* null rule */
127         | condition error { yyerror("bad actions in rule"); }
128         ;
129
130 condition:      exp
131         ;
132
133 exp:    exp AND exp 
134         | exp OR  exp 
135         | NOT exp 
136         | LPAREN exp RPAREN
137         | exp_elem
138         ;
139
140 exp_elem:       METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP,
141                                                         STRING_ST, 
142                                                         METHOD_O,
143                                                         $3);
144                                         }
145                 | METHOD EQUAL_T ID     {$$ = mk_elem(  EQUAL_OP,
146                                                         STRING_ST,
147                                                         METHOD_O,
148                                                         $3); 
149                                         }
150                 | METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
151                 | METHOD MATCH STRING   {$$ = mk_elem(  MATCH_OP,
152                                                         STRING_ST,
153                                                         METHOD_O,
154                                                         $3); 
155                                         }
156                 | METHOD MATCH ID       {$$ = mk_elem(  MATCH_OP,
157                                                         STRING_ST,
158                                                         METHOD_O,
159                                                         $3); 
160                                         }
161                 | METHOD MATCH error { $$=0; yyerror("string expected"); }
162                 | METHOD error  { $$=0; 
163                                   yyerror("invalid operator,"
164                                                 "== or ~= expected");
165                                 }
166                 | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP,
167                                                         STRING_ST,
168                                                         URI_O,
169                                                         $3); 
170                                         }
171                 | URI EQUAL_T ID        {$$ = mk_elem(  EQUAL_OP,
172                                                         STRING_ST,
173                                                         URI_O,
174                                                         $3); 
175                                         }
176                 | URI EQUAL_T error { $$=0; yyerror("string expected"); }
177                 | URI MATCH STRING 
178                 | URI MATCH ID
179                 | URI MATCH error {  $$=0; yyerror("string expected"); }
180                 | URI error     { $$=0; 
181                                   yyerror("invalid operator,"
182                                                 " == or ~= expected");
183                                 }
184                 | SRCIP EQUAL_T net4 
185                 | SRCIP EQUAL_T STRING 
186                 | SRCIP EQUAL_T host
187                 | SRCIP EQUAL_T error { yyerror( "ip address or hostname"
188                                                  "expected" ); }
189                 | SRCIP MATCH STRING
190                 | SRCIP MATCH ID
191                 | SRCIP MATCH error  { yyerror( "hostname expected"); }
192                 | SRCIP error  {yyerror("invalid operator, == or ~= expected");}
193                 | DSTIP EQUAL_T net4 
194                 | DSTIP EQUAL_T STRING
195                 | DSTIP EQUAL_T host
196                 | DSTIP EQUAL_T error { yyerror( "ip address or hostname"
197                                                  "expected" ); }
198                 | DSTIP MATCH STRING
199                 | DSTIP MATCH ID
200                 | DSTIP MATCH error  { yyerror ( "hostname  expected" ); }
201                 | DSTIP error {yyerror("invalid operator, == or ~= expected");}
202         ;
203
204 net4:   ipv4 SLASH ipv4 
205         | ipv4 SLASH NUMBER 
206         | ipv4
207         | ipv4 SLASH error {yyerror("netmask (eg:255.0.0.0 or 8) expected");}
208         ;
209
210 host:   ID
211         | host DOT ID
212         | host DOT error { yyerror("invalid hostname"); }
213         ;
214
215
216 actions:        actions action 
217                 | action
218                 | actions error { yyerror("bad command"); }
219         ;
220
221 action:         cmd SEMICOLON
222                 | SEMICOLON /* null action */
223                 | cmd error { yyerror("bad command: missing ';'?"); }
224         ;
225
226 cmd:            FORWARD LPAREN host RPAREN 
227                 | FORWARD LPAREN STRING RPAREN 
228                 | FORWARD LPAREN ipv4 RPAREN 
229                 | FORWARD LPAREN host COMMA NUMBER RPAREN
230                 | FORWARD LPAREN STRING COMMA NUMBER RPAREN
231                 | FORWARD LPAREN ipv4 COMMA NUMBER RPAREN
232                 | FORWARD error { yyerror("missing '(' or ')' ?"); }
233                 | FORWARD LPAREN error RPAREN { yyerror("bad forward"
234                                                 "argument"); }
235                 | SEND LPAREN host RPAREN 
236                 | SEND LPAREN STRING RPAREN 
237                 | SEND LPAREN ipv4 RPAREN
238                 | SEND LPAREN host COMMA NUMBER RPAREN
239                 | SEND LPAREN STRING COMMA NUMBER RPAREN
240                 | SEND LPAREN ipv4 COMMA NUMBER RPAREN
241                 | SEND error { yyerror("missing '(' or ')' ?"); }
242                 | SEND LPAREN error RPAREN { yyerror("bad send"
243                                                 "argument"); }
244                 | DROP LPAREN RPAREN 
245                 | DROP 
246                 | LOG LPAREN STRING RPAREN
247                 | LOG LPAREN NUMBER COMMA STRING RPAREN
248                 | LOG error { yyerror("missing '(' or ')' ?"); }
249                 | LOG LPAREN error RPAREN { yyerror("bad log"
250                                                 "argument"); }
251                 | ERROR LPAREN STRING COMMA STRING RPAREN 
252                 | ERROR error { yyerror("missing '(' or ')' ?"); }
253                 | ERROR LPAREN error RPAREN { yyerror("bad error"
254                                                 "argument"); }
255                 | ROUTE LPAREN NUMBER RPAREN
256                 | ROUTE error { yyerror("missing '(' or ')' ?"); }
257                 | ROUTE LPAREN error RPAREN { yyerror("bad route"
258                                                 "argument"); }
259         ;
260
261
262 %%
263
264 extern int line;
265 extern int column;
266 yyerror(char* s)
267 {
268         fprintf(stderr, "parse error (%d,%d): %s\n", line, column, s);
269 }
270
271 int main(int argc, char ** argv)
272 {
273         if (yyparse()!=0)
274                 fprintf(stderr, "parsing error\n");
275 }