Revision b8cc390e filter/config.Y

View differences:

filter/config.Y
12 12

  
13 13
CF_DEFINES
14 14

  
15
#define P(a,b) ((a<<8) | b)
15
#define P(a,b) ((a << 8) | b)
16 16

  
17
static int make_pair(int i1, int i2)
17
static inline u32 pair(u32 a, u32 b) { return (a << 16) | b; }
18
static inline u32 pair_a(u32 p) { return p >> 16; }
19
static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
20

  
21

  
22
/*
23
 * Sets and their items are during parsing handled as lists, linked
24
 * through left ptr. The first item in a list also contains a pointer
25
 * to the last item in a list (right ptr). For convenience, even items
26
 * are handled as one-item lists. Lists are merged by f_merge_items().
27
 */
28

  
29
static inline struct f_tree *
30
f_new_item(struct f_val from, struct f_val to)
18 31
{
19
  unsigned u1 = i1;
20
  unsigned u2 = i2;
32
  struct f_tree *t = f_new_tree();
33
  t->right = t;
34
  t->from = from;
35
  t->to = to;
36
  return t;
37
}
21 38

  
22
  if ((u1 > 0xFFFF) || (u2 > 0xFFFF))
23
    cf_error( "Can't operate with value out of bounds in pair constructor");
39
static inline struct f_tree *
40
f_merge_items(struct f_tree *a, struct f_tree *b)
41
{
42
  if (!a) return b;
43
  a->right->left = b;
44
  a->right = b->right;
45
  b->right = NULL;
46
  return a;
47
}
24 48

  
25
  return (u1 << 16) | u2;
49
static inline struct f_tree *
50
f_new_pair_item(int fa, int ta, int fb, int tb)
51
{
52
  struct f_tree *t = f_new_tree();
53
  t->right = t;
54
  t->from.type = t->to.type = T_PAIR;
55
  t->from.val.i = pair(fa, fb);
56
  t->to.val.i = pair(ta, tb);
57
  return t;
26 58
}
27 59

  
28
struct f_tree *f_generate_rev_wcard(int from, int to, int expr)
60
static inline struct f_tree *
61
f_new_pair_set(int fa, int ta, int fb, int tb)
29 62
{
30
	struct f_tree *ret = NULL, *last = NULL;
63
  struct f_tree *lst = NULL;
64
  int i;
31 65

  
32
	while (from <= to) {
33
		ret = f_new_tree(); 
34
		ret->from.type = ret->to.type = T_PAIR;
35
		ret->from.val.i = ret->to.val.i = make_pair(from, expr); 
36
		ret->left = last;
66
  if ((fa == ta) || ((fb == 0) && (tb == 0xFFFF)))
67
    return f_new_pair_item(fa, ta, fb, tb);
68
  
69
  if ((ta < fa) || (tb < fb))
70
    cf_error( "From value cannot be higher that To value in pair sets");
37 71

  
38
		from++; last = ret;
39
	}
40
	return ret;
72
  for (i = fa; i <= ta; i++)
73
    lst = f_merge_items(lst, f_new_pair_item(i, i, fb, tb));
74

  
75
  return lst;
41 76
}
42 77

  
43 78
CF_DECLS
......
60 95

  
61 96
%type <x> term block cmds cmds_int cmd function_body constant print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol dpair bgp_path_expr
62 97
%type <f> filter filter_body where_filter
63
%type <i> type break_command
64
%type <e> set_item set_items switch_body
98
%type <i> type break_command pair_expr
99
%type <i32> pair_atom
100
%type <e> pair_item set_item switch_item set_items switch_items switch_body
65 101
%type <trie> fprefix_set
66
%type <v> set_atom fprefix fprefix_s fipa
102
%type <v> set_atom switch_atom fprefix fprefix_s fipa
67 103
%type <s> decls declsn one_decl function_params 
68 104
%type <h> bgp_path bgp_path_tail1 bgp_path_tail2
69 105

  
......
243 279
   IPA %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
244 280
 ;
245 281

  
282

  
283

  
284
/*
285
 * Set constants. They are also used in switch cases. We use separate
286
 * nonterminals for switch (set_atom/switch_atom, set_item/switch_item ...)
287
 * to elude a collision between symbol (in expr) in set_atom and symbol
288
 * as a function call in switch case cmds.
289
 */
290

  
246 291
set_atom:
247
   expr  { $$.type = T_INT; $$.val.i = $1; }	/* 'SYM' included in 'expr' creates 3 reduce/shift conflicts */
292
   expr  { $$.type = T_INT; $$.val.i = $1; }
248 293
 | RTRID { $$.type = T_QUAD; $$.val.i = $1; }
249 294
 | fipa  { $$ = $1; }
250
 | ENUM  { $$.type = $1 >> 16; $$.val.i = $1 & 0xffff; }
251
 ; 
295
 | ENUM  { $$.type = pair_a($1); $$.val.i = pair_b($1); }
296
 ;
252 297

  
253
set_item:
254
   '(' expr ',' expr ')' {
255
	$$ = f_new_tree(); 
256
	$$->from.type = $$->to.type = T_PAIR;
257
	$$->from.val.i = make_pair($2, $4); 
258
	$$->to.val.i = make_pair($2, $4);
259
   }
260
 | '(' expr ',' expr '.' '.' expr ')' { 
261
	$$ = f_new_tree(); 
262
	$$->from.type = $$->to.type = T_PAIR;
263
	$$->from.val.i = make_pair($2, $4); 
264
	$$->to.val.i = make_pair($2, $7);
265
   }
266
 | '(' expr ',' expr ')' '.' '.' '(' expr ',' expr ')' { 
267
	$$ = f_new_tree(); 
268
	$$->from.type = $$->to.type = T_PAIR;
269
	$$->from.val.i = make_pair($2, $4); 
270
	$$->to.val.i = make_pair($9, $11);
271
   }
272
 |  '(' '*' ',' '*' ')' { 	/* This is probably useless :-) */
273
	$$ = f_new_tree(); 
274
	$$->from.type = $$->to.type = T_PAIR;
275
	$$->from.val.i = 0;
276
	$$->to.val.i = 0xffffffff;
277
   }
278
 |  '(' expr ',' '*' ')' { 
279
	$$ = f_new_tree(); 
280
	$$->from.type = $$->to.type = T_PAIR;
281
	$$->from.val.i = make_pair($2, 0); 
282
	$$->to.val.i = make_pair($2, 0xffff);
283
   }
284
 |  '(' '*' ',' expr ')' { 
285
	$$ = f_generate_rev_wcard(0, 0xffff, $4);
286
   }
287
 /* This causes 3 reduce/reduce conflicts
288
 | '(' expr '.' '.' expr ',' expr ')' { 
289
	cf_error("Not implemented yet");
290
   }*/
291
 | set_atom { 
292
	$$ = f_new_tree(); 
293
	$$->from = $1; 
294
	$$->to = $1;
298
switch_atom:
299
   NUM   { $$.type = T_INT; $$.val.i = $1; }
300
 | '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int($2); }
301
 | RTRID { $$.type = T_QUAD; $$.val.i = $1; }
302
 | fipa  { $$ = $1; }
303
 | ENUM  { $$.type = pair_a($1); $$.val.i = pair_b($1); }
304
 ;
305

  
306
pair_expr:
307
   term { $$ = f_eval_int($1); check_u16($$); }
308

  
309
pair_atom:
310
   pair_expr { $$ = pair($1, $1); }
311
 | pair_expr DDOT pair_expr { $$ = pair($1, $3); }
312
 | '*' { $$ = 0xFFFF; }
313
 ;
314

  
315
pair_item:
316
   '(' pair_atom ',' pair_atom ')' {
317
     $$ = f_new_pair_set(pair_a($2), pair_b($2), pair_a($4), pair_b($4));
295 318
   }
296
 | set_atom '.' '.' set_atom { 
297
	$$ = f_new_tree(); 
298
	$$->from = $1; 
299
	$$->to = $4; 
319
 | '(' pair_atom ',' pair_atom ')' DDOT '(' pair_expr ',' pair_expr ')' {
320
     /* Hack: $2 and $4 should be pair_expr, but that would cause shift/reduce conflict */
321
     if ((pair_a($2) != pair_b($2)) || (pair_a($4) != pair_b($4)))
322
       cf_error("syntax error");
323
     $$ = f_new_pair_item(pair_b($2), pair_b($4), $8, $10); 
300 324
   }
301 325
 ;
302 326

  
327
set_item:
328
   pair_item
329
 | set_atom { $$ = f_new_item($1, $1); }
330
 | set_atom DDOT set_atom { $$ = f_new_item($1, $3); }
331
 ;
332

  
333
switch_item:
334
   pair_item
335
 | switch_atom { $$ = f_new_item($1, $1); }
336
 | switch_atom DDOT switch_atom { $$ = f_new_item($1, $3); }
337
 ;
338

  
303 339
set_items:
304
   set_item { $$ = $1; }
305
 | set_items ',' set_item { $$ = $3; $$->left = $1; }
340
   set_item
341
 | set_items ',' set_item { $$ = f_merge_items($1, $3); }
342
 ;
343

  
344
switch_items:
345
   switch_item
346
 | switch_items ',' switch_item { $$ = f_merge_items($1, $3); }
306 347
 ;
307 348

  
308 349
fprefix_s:
......
328 369
 ;
329 370

  
330 371
switch_body: /* EMPTY */ { $$ = NULL; }
331
 | switch_body set_item ':' cmds  {
332
     $$ = $2;
333
     $$->data = $4;
334
     $$->left = $1;
335
   }
336
 | switch_body ELSECOL cmds {
337
     $$ = f_new_tree(); 
338
     $$->from.type = T_VOID; 
339
     $$->to.type = T_VOID;
340
     $$->data = $3;
341
     $$->left = $1;
342
   }
372
 | switch_body switch_items ':' cmds  {
373
     /* Fill data fields */
374
     struct f_tree *t;
375
     for (t = $2; t; t = t->left)
376
       t->data = $4;
377
     $$ = f_merge_items($1, $2);
378
   }
379
 | switch_body ELSECOL cmds { 
380
     struct f_tree *t = f_new_tree();
381
     t->from.type = t->to.type = T_VOID;
382
     t->right = t;
383
     t->data = $3;
384
     $$ = f_merge_items($1, t);
385
 }
343 386
 ;
344 387

  
345 388
/* CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_INT; $$->a2.i = $3; } */
......
374 417
          { 
375 418
            if (($2->aux != T_INT) || ($4->aux != T_INT))
376 419
              cf_error( "Can't operate with value of non-integer type in pair constructor" );
377
            $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR;  $$->a2.i = make_pair($2->a2.i, $4->a2.i);
420
	    check_u16($2->a2.i); check_u16($4->a2.i);
421
            $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR;  $$->a2.i = pair($2->a2.i, $4->a2.i);
378 422
          }
379 423
	else
380 424
	  { $$ = f_new_inst(); $$->code = P('m', 'p'); $$->a1.p = $2; $$->a2.p = $4; }
......
399 443
/*
400 444
 *  Maybe there are no dynamic attributes defined by protocols.
401 445
 *  For such cases, we force the dynamic_attr list to contain
402
 *  at least an invalid token, so it's syntantically correct.
446
 *  at least an invalid token, so it is syntantically correct.
403 447
 */
404 448
CF_ADDTO(dynamic_attr, INVALID_TOKEN { $$ = NULL; })
405 449

  

Also available in: Unified diff