modules/up/src/rpsl/rpsl/rpsl.y
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- yyparse
- enable_yy_parser_debugging
- handleArgumentTypeError
- searchMethod
1 %{
2 // $Id: rpsl.y,v 1.4 2001/01/14 21:23:38 engin Exp $
3 //
4 // Copyright (c) 1994 by the University of Southern California
5 // All rights reserved.
6 //
7 // Permission to use, copy, modify, and distribute this software and its
8 // documentation in source and binary forms for lawful non-commercial
9 // purposes and without fee is hereby granted, provided that the above
10 // copyright notice appear in all copies and that both the copyright
11 // notice and this permission notice appear in supporting documentation,
12 // and that any documentation, advertising materials, and other materials
13 // related to such distribution and use acknowledge that the software was
14 // developed by the University of Southern California, Information
15 // Sciences Institute. The name of the USC may not be used to endorse or
16 // promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
20 // REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
21 // PURPOSE. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
22 // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
23 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
24 // TITLE, AND NON-INFRINGEMENT.
25 //
26 // IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
27 // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
28 // OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
29 // OR PERFORMANCE OF THIS SOFTWARE.
30 //
31 // Questions concerning this software should be directed to
32 // ratoolset@isi.edu.
33 //
34 // Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
35
36 #include "config.h"
37 #include "time.h"
38 #include "schema.hh"
39 #include "object.hh"
40 #include "regexp.hh"
41 #include "rptype.hh"
42
43 #ifdef DEBUG
44 #define YYDEBUG 1
45 #endif // DEBUG
46 #if YYDEBUG != 0
47 // stdio is needed for yydebug
48 #include <cstdio>
49 #endif
50
51 extern void handle_error(char *, ...);
52 extern void handle_object_error(char *, ...);
53 extern void handle_warning(char *, ...);
54 extern int yylex();
55 char *token_name(int token_id);
56 void rpslerror(char *s, ...);
57 Attr *changeCurrentAttr(Attr *b);
58 void handleArgumentTypeError(char *attr, char *method, int position,
59 const RPType *correctType,
60 bool isOperator = false);
61 const AttrMethod *searchMethod(const AttrRPAttr *rp_attr, char *method, ItemList *args);
62
63 /* argument to yyparse result of parsing should be stored here */
64 #define YYPARSE_PARAM object
65 #define yyschema schema
66 #define enable_yy_parser_debugging enable_rpsl_parser_debugging
67
68 extern Object *current_object;
69
70 %}
71
72 %expect 1
73
74 %union {
75 long long int i;
76 double real;
77 char *string;
78 void *ptr;
79 time_t time;
80 Item *item;
81 ItemList *list;
82 regexp *re;
83 SymID sid;
84 IPAddr *ip;
85 Prefix *prfx;
86 PrefixRange *prfxrng;
87 RPType *typenode;
88
89 Filter *filter;
90 FilterMS *moreSpecOp;
91 PolicyPeering *peering;
92 PolicyActionList *actionList;
93 PolicyAction *actionNode;
94 PolicyFactor *policyFactor;
95 PolicyTerm *policyTerm;
96 PolicyExpr *policyExpr;
97 List<PolicyPeeringAction> *peeringActionList;
98
99 Attr *attr;
100 AttrAttr *rpslattr;
101 AttrMethod *method;
102 const AttrRPAttr *rp_attr;
103 const AttrProtocol *protocol;
104 AttrProtocolOption *protocol_option;
105 List<AttrProtocolOption> *protocol_option_list;
106
107 AttrPeerOption *peer_option;
108 List<AttrPeerOption> *peer_option_list;
109
110 List<RPTypeNode> *typelist;
111 List<AttrMethod> *methodlist;
112 List<WordNode> *wordlist;
113
114 List<AttrMntRoutes::MntPrfxPair> *listMntPrfxPair;
115 AttrMntRoutes::MntPrfxPair *mntPrfxPair;
116 }
117
118 %token KEYW_TRUE
119 %token KEYW_FALSE
120 %token KEYW_ACTION
121 %token KEYW_ACCEPT
122 %token KEYW_ANNOUNCE
123 %token KEYW_FROM
124 %token KEYW_TO
125 %token KEYW_AT
126 %token KEYW_ANY
127 %token KEYW_REFINE
128 %token KEYW_EXCEPT
129 %token KEYW_STATIC
130 %token KEYW_NETWORKS
131 %token KEYW_MASKLEN
132 %token KEYW_UNION
133 %token KEYW_RANGE
134 %token KEYW_LIST
135 %token KEYW_OF
136 %token KEYW_OPERATOR
137 %token KEYW_SYNTAX
138 %token KEYW_SPECIAL
139 %token KEYW_OPTIONAL
140 %token KEYW_MANDATORY
141 %token KEYW_INTERNAL
142 %token KEYW_SINGLEVALUED
143 %token KEYW_MULTIVALUED
144 %token KEYW_LOOKUP
145 %token KEYW_KEY
146 %token KEYW_DELETED
147 %token KEYW_GENERATED
148 %token KEYW_OBSOLETE
149 %token KEYW_PEERAS
150 %token KEYW_PROTOCOL
151 %token KEYW_INTO
152 %token KEYW_ATOMIC
153 %token KEYW_INBOUND
154 %token KEYW_OUTBOUND
155 %token KEYW_UPON
156 %token KEYW_HAVE_COMPONENTS
157 %token KEYW_EXCLUDE
158
159 %token KEYW_NONE
160 %token KEYW_MAILFROM
161 %token KEYW_CRYPTPW
162 %token KEYW_ASSIGNED
163 %token KEYW_ALLOCATED
164 %token KEYW_PI
165 %token KEYW_PA
166 %token KEYW_UNSPECIFIED
167 %token KEYW_EXT
168 %token KEYW_SIMPLE
169 %token KEYW_RIPE
170 %token KEYW_INTERNIC
171 %token KEYW_CLIENTADDRESS
172
173
174 %token TKN_ERROR
175 %token TKN_UNKNOWN_CLASS
176 %token TKN_EOA /* end of attribute */
177 %token TKN_EOO /* end of object */
178 %token TKN_FREETEXT
179 %token <i> TKN_INT
180 %token <real> TKN_REAL
181 %token <string> TKN_STRING
182 %token <time> TKN_TIMESTAMP
183 %token <string> TKN_BLOB
184 %token <ip> TKN_IPV4
185 %token <string> TKN_PRFXV6
186 %token <prfx> TKN_PRFXV4
187 %token <prfxrng> TKN_PRFXV4RNG
188 %token <i> TKN_ASNO
189 %token <sid> TKN_ASNAME
190 %token <sid> TKN_RSNAME
191 %token <sid> TKN_RTRSNAME
192 %token <sid> TKN_PRNGNAME
193 %token <sid> TKN_FLTRNAME
194 %token <i> TKN_BOOLEAN
195 %token <string> TKN_WORD
196 %token <rp_attr> TKN_RP_ATTR
197 %token <sid> TKN_DNS
198 %token <string> TKN_EMAIL
199 %token TKN_3DOTS
200
201 %token <string> TKN_NICHDL
202 %token <string> TKN_KEYCRTNAME
203 %token <string> TKN_CRYPTEDPW
204
205 %token <attr> ATTR_GENERIC
206 %token <attr> ATTR_BLOBS
207 %token <attr> ATTR_IMPORT
208 %token <attr> ATTR_EXPORT
209 %token <attr> ATTR_DEFAULT
210 %token <attr> ATTR_FREETEXT
211 %token <attr> ATTR_CHANGED
212 %token <attr> ATTR_IFADDR
213 %token <attr> ATTR_PEER
214 %token <attr> ATTR_INJECT
215 %token <attr> ATTR_COMPONENTS
216 %token <attr> ATTR_AGGR_MTD
217 %token <attr> ATTR_AGGR_BNDRY
218 %token <attr> ATTR_RS_MEMBERS
219 %token <attr> ATTR_RP_ATTR
220 %token <attr> ATTR_TYPEDEF
221 %token <attr> ATTR_PROTOCOL
222 %token <attr> ATTR_FILTER
223 %token <attr> ATTR_PEERING
224 %token <attr> ATTR_ATTR
225 %token <attr> ATTR_MNT_ROUTES
226
227 %token <attr> ATTR_NICHDL
228 %token <attr> ATTR_AUTH
229 %token <attr> ATTR_STATUS_INET
230 %token <attr> ATTR_PHONE
231 %token <attr> ATTR_SOURCE
232 %token <attr> ATTR_REFER
233 %token <attr> ATTR_COUNTRY
234 %token <attr> ATTR_PERSON
235
236 %left OP_OR
237 %left OP_AND
238 %right OP_NOT
239 %nonassoc<moreSpecOp> OP_MS
240 %nonassoc<string> TKN_OPERATOR
241
242 %type<list> generic_list
243 %type<list> rs_members_list
244 %type<list> opt_rs_members_list
245 %type<list> blobs_list
246 %type<list> generic_non_empty_list
247 %type<item> list_item
248 %type<item> list_item_0
249 %type<item> rs_member
250
251 %type<string> tkn_word
252 %type<string> tkn_word_from_keyw
253
254 %type<string> tkn_word_from_keyw_none
255 %type<string> tkn_word_from_keyw_mailfrom
256 %type<string> tkn_word_from_keyw_cryptpw
257 %type<string> tkn_word_from_keyw_assigned
258 %type<string> tkn_word_from_keyw_allocated
259 %type<string> tkn_word_from_keyw_pi
260 %type<string> tkn_word_from_keyw_pa
261 %type<string> tkn_word_from_keyw_unspecified
262 %type<string> tkn_word_from_keyw_ext
263 %type<string> tkn_word_from_keyw_simple
264 %type<string> tkn_word_from_keyw_ripe
265 %type<string> tkn_word_from_keyw_internic
266 %type<string> tkn_word_from_keyw_clientaddress
267
268 %type<attr> attribute
269 %type<attr> generic_attribute
270 %type<attr> blobs_attribute
271 %type<attr> changed_attribute
272 %type<attr> ifaddr_attribute
273 %type<attr> peer_attribute
274 %type<attr> components_attribute
275 %type<attr> inject_attribute
276 %type<attr> aggr_mtd_attribute
277 %type<attr> aggr_bndry_attribute
278
279 %type<attr> import_attribute
280 %type<attr> export_attribute
281 %type<attr> default_attribute
282 %type<attr> typedef_attribute
283 %type<attr> rpattr_attribute
284 %type<attr> rs_members_attribute
285 %type<attr> protocol_attribute
286 %type<attr> filter_attribute
287 %type<attr> peering_attribute
288 %type<attr> attr_attribute
289 %type<attr> freetext_attribute
290 %type<attr> mnt_routes_attribute
291
292 %type<attr> nichdl_attribute
293 %type<attr> auth_attribute
294 %type<attr> status_inet_attribute
295 %type<attr> phone_attribute
296 %type<attr> source_attribute
297 %type<attr> refer_attribute
298 %type<attr> country_attribute
299 %type<attr> person_attribute
300
301 %type<filter> filter
302 %type<filter> opt_default_filter
303 %type<filter> filter_term
304 %type<filter> filter_factor
305 %type<filter> filter_operand
306 %type<filter> filter_prefix
307 %type<filter> filter_prefix_operand
308 %type<filter> opt_filter_prefix_list
309 %type<filter> filter_prefix_list
310 %type<prfxrng> filter_prefix_list_prefix
311 %type<filter> filter_rp_attribute
312
313 %type<filter> opt_as_expr
314 %type<filter> as_expr
315 %type<filter> as_expr_term
316 %type<filter> as_expr_factor
317 %type<filter> as_expr_operand
318
319 %type<filter> opt_router_expr
320 %type<filter> opt_router_expr_with_at
321 %type<filter> router_expr
322 %type<filter> router_expr_term
323 %type<filter> router_expr_factor
324 %type<filter> router_expr_operand
325
326 %type<filter> opt_inject_expr
327 %type<filter> inject_expr
328 %type<filter> inject_expr_term
329 %type<filter> inject_expr_factor
330 %type<filter> inject_expr_operand
331
332 %type<re> filter_aspath
333 %type<re> filter_aspath_term
334 %type<re> filter_aspath_closure
335 %type<re> filter_aspath_factor
336 %type<re> filter_aspath_no
337 %type<re> filter_aspath_range
338
339 %type<actionList> action
340 %type<actionList> opt_action
341 %type<actionNode> single_action
342
343 %type<peering> peering
344
345 %type<peeringActionList> import_peering_action_list
346 %type<peeringActionList> export_peering_action_list
347 %type<policyFactor> import_factor
348 %type<policyTerm> import_factor_list
349 %type<policyTerm> import_term
350 %type<policyExpr> import_expr
351 %type<policyFactor> export_factor
352 %type<policyTerm> export_factor_list
353 %type<policyTerm> export_term
354 %type<policyExpr> export_expr
355 %type<protocol> opt_protocol_from
356 %type<protocol> opt_protocol_into
357
358 %type<wordlist> enum_list
359 %type<typenode> typedef_type
360 %type<typelist> typedef_type_list
361
362 %type<method> method
363 %type<methodlist> methods
364
365 %type<protocol_option> protocol_option
366 %type<protocol_option_list> protocol_options
367
368 %type<peer_option> peer_option
369 %type<peer_option_list> peer_options
370 %type<peer_option_list> opt_peer_options
371 %type<ip> peer_id
372
373 %type<rpslattr> opt_attr_options
374 %type<rpslattr> attr_options
375 %type<rpslattr> attr_option
376
377 %type<listMntPrfxPair> mnt_routes_list
378 %type<mntPrfxPair> mnt_routes_list_item
379
380 %type<string> int_list
381 %type<string> name_list
382
383 %%
/* [<][>][^][v][top][bottom][index][help] */
384 object: attribute_list TKN_EOO {
385 YYACCEPT;
386 }
387 | TKN_UNKNOWN_CLASS TKN_EOO {
388 YYACCEPT;
389 }
390 | error TKN_EOO {
391 handle_object_error("Error: syntax error\n");
392 YYABORT;
393 }
394 | attribute_list { // end of file
395 YYACCEPT;
396 }
397 | TKN_UNKNOWN_CLASS { // end of file
398 YYACCEPT;
399 }
400 | error { // end of file
401 handle_object_error("Error: syntax error\n");
402 YYABORT;
403 }
404 | { // end of file
405 YYABORT;
406 }
407 ;
408
409 attribute_list: attribute {
410 (*current_object) += $1;
411 }
412 | attribute_list attribute {
413 (*current_object) += $2;
414 }
415 ;
416
417 attribute: generic_attribute
418 | blobs_attribute
419 | changed_attribute
420 | import_attribute
421 | export_attribute
422 | default_attribute
423 | peer_attribute
424 | ifaddr_attribute
425 | components_attribute
426 | inject_attribute
427 | aggr_mtd_attribute
428 | aggr_bndry_attribute
429 | typedef_attribute
430 | protocol_attribute
431 | rpattr_attribute
432 | rs_members_attribute
433 | filter_attribute
434 | peering_attribute
435 | attr_attribute
436 | freetext_attribute
437 | mnt_routes_attribute
438 | nichdl_attribute
439 | auth_attribute
440 | status_inet_attribute
441 | phone_attribute
442 | source_attribute
443 | refer_attribute
444 | country_attribute
445 | person_attribute
446 | TKN_ERROR TKN_EOA { // the current line started w/ non-attribute
447 $$ = changeCurrentAttr(new Attr);
448 handle_error("Error: syntax error\n");
449 }
450 | error TKN_EOA {
451 $$ = changeCurrentAttr(new Attr);
452 handle_error("Error: syntax error\n");
453 yyerrok;
454 }
455 ;
456
457 //**** Generic Attributes ************************************************
458
459 changed_attribute: ATTR_CHANGED TKN_EMAIL TKN_INT TKN_EOA {
460 free($2);
461 $$ = $1;
462 }
463 | ATTR_CHANGED TKN_EMAIL TKN_EOA {
464 free($2);
465 $$ = $1;
466 }
467 | ATTR_CHANGED error TKN_EOA {
468 handle_error("Error: \"changed: <email> <YYYYMMDD>\" expected\n");
469 yyerrok;
470 }
471 ;
472
473
474 nichdl_attribute: ATTR_NICHDL TKN_NICHDL TKN_EOA {
475 free($2);
476 $$ = $1;
477 }
478 | ATTR_NICHDL error TKN_EOA {
479 handle_error("Error: \"%s: <nic-handle>\" expected\n",$1->type->name());
480 yyerrok;
481 }
482
483 auth_attribute: ATTR_AUTH tkn_word_from_keyw_none TKN_EOA {
484 $$ = $1;
485 }
486 | ATTR_AUTH tkn_word_from_keyw_mailfrom TKN_EMAIL TKN_EOA {
487 free($3);
488 $$ = $1;
489 }
490 | ATTR_AUTH tkn_word_from_keyw_cryptpw TKN_CRYPTEDPW TKN_EOA {
491 free($3);
492 $$ = $1;
493 }
494 | ATTR_AUTH TKN_KEYCRTNAME TKN_EOA {
495 free($2);
496 $$ = $1;
497 }
498 | ATTR_AUTH error TKN_EOA {
499 handle_error("Error: \"auth: MAIL-FROM <regexp>\""
500 ", \"auth: NONE\", \"auth: CRYPT-PW <cryptedpaswd>\""
501 " or \"auth: PGPKEY-<pgpid>\" expected\n");
502 yyerrok;
503
504 }
505 ;
506
507
508
509 status_inet_attribute: ATTR_STATUS_INET tkn_word_from_keyw_assigned tkn_word_from_keyw_pi TKN_EOA {
510 $$ = $1;
511 }
512 | ATTR_STATUS_INET tkn_word_from_keyw_assigned tkn_word_from_keyw_pa TKN_EOA {
513 $$ = $1;
514 }
515 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_pi TKN_EOA {
516 $$ = $1;
517 }
518 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_pa TKN_EOA {
519 $$ = $1;
520 }
521 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_unspecified TKN_EOA {
522 $$ = $1;
523 }
524 | ATTR_STATUS_INET error TKN_EOA {
525 handle_error("Error: \"status\" attribute contains invalid keywords\n");
526 yyerrok;
527 }
528 ;
529
530 phone_attribute: ATTR_PHONE '+' int_list TKN_EOA {
531 $$ = $1;
532 }
533 | ATTR_PHONE '+' int_list '(' int_list ')' int_list TKN_EOA {
534 $$ = $1;
535 }
536 | ATTR_PHONE '+' int_list tkn_word_from_keyw_ext '.' int_list TKN_EOA {
537 $$ = $1;
538 }
539 | ATTR_PHONE '+' int_list '(' int_list ')' int_list tkn_word_from_keyw_ext '.' int_list TKN_EOA {
540 $$ = $1;
541 }
542 | ATTR_PHONE error TKN_EOA {
543 handle_error("Error: intn'l phone number expected (with a preceding '+')\n");
544 yyerrok;
545 }
546
547
548 int_list: TKN_INT {
549 //sprintf($$, "%i", $1);
550 $$ = strdup("phone"); // well, sprintf($$, "%i", $1) didn't work
551 }
552 | int_list TKN_INT{
553 $$ = $1;
554 }
555 | int_list '-' TKN_INT{
556 $$ = $1;
557 }
558 | int_list '.' TKN_INT{
559 $$ = $1;
560 }
561
562
563 source_attribute: ATTR_SOURCE tkn_word TKN_EOA {
564 if(yyschema.searchSource($2)){
565 free($2);
566 $$ = $1;
567 }else{
568 free($2);
569 handle_error("Error: No such source\n");
570 }
571 }
572 | ATTR_SOURCE error TKN_EOA {
573 handle_error("Error: invalid source attribute\n");
574 yyerrok;
575 }
576
577 refer_attribute: ATTR_REFER tkn_word_from_keyw_simple TKN_DNS TKN_EOA {
578 $$ = $1;
579 }
580 | ATTR_REFER tkn_word_from_keyw_simple TKN_DNS TKN_INT TKN_EOA {
581 $$ = $1;
582 }
583 | ATTR_REFER tkn_word_from_keyw_ripe TKN_DNS TKN_EOA {
584 $$ = $1;
585 }
586 | ATTR_REFER tkn_word_from_keyw_ripe TKN_DNS TKN_INT TKN_EOA {
587 $$ = $1;
588 }
589 | ATTR_REFER tkn_word_from_keyw_internic TKN_DNS TKN_EOA {
590 $$ = $1;
591 }
592 | ATTR_REFER tkn_word_from_keyw_internic TKN_DNS TKN_INT TKN_EOA {
593 $$ = $1;
594 }
595 | ATTR_REFER tkn_word_from_keyw_clientaddress TKN_DNS TKN_EOA {
596 $$ = $1;
597 }
598 | ATTR_REFER tkn_word_from_keyw_clientaddress TKN_DNS TKN_INT TKN_EOA {
599 $$ = $1;
600 }
601 | ATTR_REFER error TKN_EOA {
602 handle_error("Error: invalid refer attribute\n");
603 yyerrok;
604 }
605
606 country_attribute: ATTR_COUNTRY tkn_word TKN_EOA {
607 if(yyschema.searchCountry($2)){
608 free($2);
609 $$ = $1;
610 }else{
611 free($2);
612 handle_error("Error: No such country\n");
613 }
614 }
615 | ATTR_COUNTRY error TKN_EOA {
616 handle_error("Error: invalid country attribute\n");
617 yyerrok;
618 }
619
620 person_attribute: ATTR_PERSON tkn_word name_list TKN_EOA {
621 $$ = $1;
622 }
623 | ATTR_PERSON error TKN_EOA {
624 handle_error("Error: invalid %s attribute\n",$1->type->name());
625 yyerrok;
626 }
627
628 name_list: tkn_word {
629 $$ = strdup($1);
630 }
631 | name_list tkn_word {
632 $$ = strdup($2);
633 }
634
635
636 freetext_attribute: ATTR_FREETEXT TKN_EOA {
637 char *start = strchr($1->object->contents + $1->offset, ':') + 1;
638 int len = $1->object->contents + $1->offset + $1->len - start;
639 ItemFREETEXT *ft = new ItemFREETEXT(start, len);
640 ItemList *il = new ItemList;
641 il->append(ft);
642
643 $$ = changeCurrentAttr(new AttrGeneric($1->type, il));
644 }
645 ;
646
647 generic_attribute: ATTR_GENERIC generic_list TKN_EOA {
648 if (!$1->type->subsyntax()->validate($2)) {
649 handle_error("Error: argument to %s should be %s.\n",
650 $1->type->name(), $1->type->subsyntax()->name());
651 delete $2;
652 $$ = changeCurrentAttr(new AttrGeneric($1->type, NULL));
653 } else
654 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
655 }
656 | ATTR_GENERIC error TKN_EOA {
657 $$ = $1;
658 cout << "issuing error: argument to %s should be %s.(ATTR_GENERIC error TKN_EOA)" << endl;
659 handle_error("Error: argument to %s should be %s.\n",
660 $1->type->name(), $1->type->subsyntax()->name());
661 yyerrok;
662 }
663 ;
664
665 generic_list: /* empty list */ {
666 $$ = new ItemList;
667 }
668 | generic_non_empty_list
669 ;
670
671 generic_non_empty_list: list_item {
672 $$ = new ItemList;
673 $$->append($1);
674 }
675 | generic_non_empty_list ',' list_item {
676 $$ = $1;
677 $$->append($3);
678 }
679 ;
680
681 blobs_attribute: ATTR_BLOBS blobs_list TKN_EOA {
682 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
683 }
684 | ATTR_BLOBS error TKN_EOA {
685 $$ = $1;
686 handle_error("Error: argument to %s should be blob sequence.\n",
687 $1->type->name());
688 yyerrok;
689 }
690 ;
691
692 blobs_list: list_item {
693 $$ = new ItemList;
694 $$->append($1);
695 }
696 | blobs_list list_item {
697 $$ = $1;
698 $$->append($2);
699 }
700 ;
701
702 list_item: list_item_0 {
703 $$ = $1;
704 }
705 | list_item_0 '-' list_item_0 {
706 $$ = new ItemRange($1, $3);
707 }
708 ;
709
710 list_item_0: TKN_ASNO {
711 $$ = new ItemASNO($1);
712 }
713 | TKN_INT {
714 $$ = new ItemINT($1);
715 }
716 | TKN_REAL {
717 $$ = new ItemREAL($1);
718 }
719 | TKN_STRING {
720 $$ = new ItemSTRING($1);
721 }
722 | TKN_TIMESTAMP {
723 $$ = new ItemTimeStamp($1);
724 }
725 | TKN_IPV4 {
726 $$ = new ItemIPV4($1);
727 }
728 | TKN_PRFXV4 {
729 $$ = new ItemPRFXV4($1);
730 }
731 | TKN_PRFXV6 {
732 $$ = new ItemPRFXV6($1);
733 }
734 | TKN_PRFXV4RNG {
735 $$ = new ItemPRFXV4Range($1);
736 }
737 | TKN_IPV4 ':' TKN_INT {
738 $$ = new ItemConnection($1, $3);
739 }
740 | TKN_IPV4 ':' TKN_INT ':' TKN_INT {
741 $$ = new ItemConnection($1, $3, $5);
742 }
743 | TKN_DNS ':' TKN_INT {
744 $$ = new ItemConnection($1, $3);
745 }
746 | TKN_DNS ':' TKN_INT ':' TKN_INT {
747 $$ = new ItemConnection($1, $3, $5);
748 }
749 | TKN_ASNAME {
750 $$ = new ItemASNAME($1);
751 }
752 | TKN_RSNAME {
753 $$ = new ItemRSNAME($1);
754 }
755 | TKN_RTRSNAME {
756 $$ = new ItemRTRSNAME($1);
757 }
758 | TKN_PRNGNAME {
759 $$ = new ItemPRNGNAME($1);
760 }
761 | TKN_FLTRNAME {
762 $$ = new ItemFLTRNAME($1);
763 }
764 | TKN_BOOLEAN {
765 $$ = new ItemBOOLEAN($1);
766 }
767 | TKN_WORD {
768 $$ = new ItemWORD($1);
769 }
770 | tkn_word_from_keyw {
771 $$ = new ItemWORD($1);
772 }
773 | TKN_DNS {
774 $$ = new ItemDNS($1);
775 }
776 | TKN_EMAIL {
777 $$ = new ItemEMAIL($1);
778 }
779 | TKN_KEYCRTNAME {
780 $$ = new ItemKEYCRTNAME($1);
781 }
782 | TKN_BLOB {
783 $$ = new ItemBLOB($1);
784 }
785 | '{' generic_list '}' {
786 $$ = $2;
787 }
788 | '(' filter ')' {
789 $$ = new ItemFilter($2);
790 }
791 ;
792
793 tkn_word: TKN_WORD {
794 $$ = $1;
795 }
796 | TKN_ASNO {
797 char buffer[64];
798 sprintf(buffer, "AS%d", $1);
799 $$ = strdup(buffer);
800 }
801 | TKN_ASNAME {
802 $$ = strdup($1);
803 }
804 | TKN_RSNAME {
805 $$ = strdup($1);
806 }
807 | TKN_RTRSNAME {
808 $$ = strdup($1);
809 }
810 | TKN_PRNGNAME {
811 $$ = strdup($1);
812 }
813 | TKN_FLTRNAME {
814 $$ = strdup($1);
815 }
816 | TKN_NICHDL {
817 $$ = strdup($1);
818 }
819 | TKN_BOOLEAN {
820 if ($1)
821 $$ = strdup("true");
822 else
823 $$ = strdup("false");
824 }
825 | tkn_word_from_keyw
826 | tkn_word_from_keyw_ripe
827 | tkn_word_from_keyw_internic
828 | tkn_word_from_keyw_simple
829 | tkn_word_from_keyw_clientaddress
830 ;
831
832 tkn_word_from_keyw: KEYW_TRUE {
833 $$ = strdup("true");
834 }
835 | KEYW_FALSE {
836 $$ = strdup("false");
837 }
838 | KEYW_ACTION {
839 $$ = strdup("action");
840 }
841 | KEYW_ACCEPT {
842 $$ = strdup("accept");
843 }
844 | KEYW_ANNOUNCE {
845 $$ = strdup("announce");
846 }
847 | KEYW_FROM {
848 $$ = strdup("from");
849 }
850 | KEYW_TO {
851 $$ = strdup("to");
852 }
853 | KEYW_AT {
854 $$ = strdup("at");
855 }
856 | KEYW_ANY {
857 $$ = strdup("any");
858 }
859 | KEYW_REFINE {
860 $$ = strdup("refine");
861 }
862 | KEYW_EXCEPT {
863 $$ = strdup("except");
864 }
865 | KEYW_STATIC {
866 $$ = strdup("static");
867 }
868 | KEYW_NETWORKS {
869 $$ = strdup("networks");
870 }
871 | KEYW_MASKLEN {
872 $$ = strdup("masklen");
873 }
874 | KEYW_UNION {
875 $$ = strdup("union");
876 }
877 | KEYW_RANGE {
878 $$ = strdup("range");
879 }
880 | KEYW_LIST {
881 $$ = strdup("list");
882 }
883 | KEYW_OF {
884 $$ = strdup("of");
885 }
886 | KEYW_OPERATOR {
887 $$ = strdup("operator");
888 }
889 | KEYW_SYNTAX {
890 $$ = strdup("syntax");
891 }
892 | KEYW_SPECIAL {
893 $$ = strdup("special");
894 }
895 | KEYW_OPTIONAL {
896 $$ = strdup("optional");
897 }
898 | KEYW_MANDATORY {
899 $$ = strdup("mandatory");
900 }
901 | KEYW_INTERNAL {
902 $$ = strdup("internal");
903 }
904 | KEYW_DELETED {
905 $$ = strdup("deleted");
906 }
907 | KEYW_SINGLEVALUED {
908 $$ = strdup("singlevalued");
909 }
910 | KEYW_GENERATED {
911 $$ = strdup("generated");
912 }
913 | KEYW_MULTIVALUED {
914 $$ = strdup("multivalued");
915 }
916 | KEYW_LOOKUP {
917 $$ = strdup("lookup");
918 }
919 | KEYW_KEY {
920 $$ = strdup("key");
921 }
922 | KEYW_OBSOLETE {
923 $$ = strdup("obsolete");
924 }
925 | KEYW_PEERAS {
926 $$ = strdup("peeras");
927 }
928 | KEYW_PROTOCOL {
929 $$ = strdup("protocol");
930 }
931 | KEYW_INTO {
932 $$ = strdup("into");
933 }
934 | KEYW_ATOMIC {
935 $$ = strdup("atomic");
936 }
937 | KEYW_INBOUND {
938 $$ = strdup("inbound");
939 }
940 | KEYW_OUTBOUND {
941 $$ = strdup("outbound");
942 }
943 ;
944
945 tkn_word_from_keyw_none: KEYW_NONE {
946 $$ = strdup("none");
947 }
948
949 tkn_word_from_keyw_mailfrom: KEYW_MAILFROM {
950 $$ = strdup("mail-from");
951 }
952
953 tkn_word_from_keyw_cryptpw: KEYW_CRYPTPW {
954 $$ = strdup("crypt-pw");
955 }
956
957 tkn_word_from_keyw_assigned: KEYW_ASSIGNED {
958 $$ = strdup("assigned");
959 }
960
961 tkn_word_from_keyw_allocated: KEYW_ALLOCATED {
962 $$ = strdup("allocated");
963 }
964
965 tkn_word_from_keyw_pi: KEYW_PI {
966 $$ = strdup("pi");
967 }
968
969 tkn_word_from_keyw_pa: KEYW_PA {
970 $$ = strdup("pa");
971 }
972
973 tkn_word_from_keyw_unspecified: KEYW_UNSPECIFIED {
974 $$ = strdup("unspecified");
975 }
976
977 tkn_word_from_keyw_ext: KEYW_EXT {
978 $$ = strdup("ext");
979 }
980
981 tkn_word_from_keyw_simple: KEYW_SIMPLE {
982 $$ = strdup("simple");
983 }
984
985 tkn_word_from_keyw_ripe: KEYW_RIPE {
986 $$ = strdup("ripe");
987 }
988
989 tkn_word_from_keyw_internic: KEYW_INTERNIC {
990 $$ = strdup("internic");
991 }
992
993 tkn_word_from_keyw_clientaddress: KEYW_CLIENTADDRESS {
994 $$ = strdup("clientaddress");
995 }
996
997
998 //**** aut-num class ******************************************************
999
1000 //// as_expr ////////////////////////////////////////////////////////////
1001
1002 opt_as_expr: {
1003 $$ = new FilterASNAME(symbols.symID("AS-ANY"));
1004 }
1005 | as_expr
1006 ;
1007
1008 as_expr: as_expr OP_OR as_expr_term {
1009 $$ = new FilterOR($1, $3);
1010 }
1011 | as_expr_term
1012 ;
1013
1014 as_expr_term: as_expr_term OP_AND as_expr_factor {
1015 $$ = new FilterAND($1, $3);
1016 }
1017 | as_expr_term KEYW_EXCEPT as_expr_factor {
1018 $$ = new FilterEXCEPT($1, $3);
1019 }
1020 | as_expr_factor
1021 ;
1022
1023 as_expr_factor: '(' as_expr ')' {
1024 $$ = $2;
1025 }
1026 | as_expr_operand
1027 ;
1028
1029 as_expr_operand: TKN_ASNO {
1030 $$ = new FilterASNO($1);
1031 }
1032 | TKN_ASNAME {
1033 $$ = new FilterASNAME($1);
1034 }
1035 ;
1036
1037 //// router_expr ///////////////////////////////////////////////////////////
1038
1039 opt_router_expr: {
1040 $$ = new FilterANY;
1041 }
1042 | router_expr {
1043 $$ = $1;
1044 }
1045 ;
1046
1047 opt_router_expr_with_at: {
1048 $$ = new FilterANY;
1049 }
1050 | KEYW_AT router_expr {
1051 $$ = $2;
1052 }
1053 ;
1054
1055 router_expr: router_expr OP_OR router_expr_term {
1056 $$ = new FilterOR($1, $3);
1057 }
1058 | router_expr_term
1059 ;
1060
1061 router_expr_term: router_expr_term OP_AND router_expr_factor {
1062 $$ = new FilterAND($1, $3);
1063 }
1064 | router_expr_term KEYW_EXCEPT router_expr_factor {
1065 $$ = new FilterEXCEPT($1, $3);
1066 }
1067 | router_expr_factor
1068 ;
1069
1070 router_expr_factor: '(' router_expr ')' {
1071 $$ = $2;
1072 }
1073 | router_expr_operand
1074 ;
1075
1076 router_expr_operand: TKN_IPV4 {
1077 $$ = new FilterRouter($1);
1078 }
1079 | TKN_DNS {
1080 $$ = new FilterRouterName($1);
1081 }
1082 | TKN_RTRSNAME {
1083 $$ = new FilterRTRSNAME($1);
1084 }
1085 ;
1086
1087 //// peering ////////////////////////////////////////////////////////////
1088
1089 peering: as_expr opt_router_expr opt_router_expr_with_at {
1090 $$ = new PolicyPeering($1, $2, $3);
1091 }
1092 | TKN_PRNGNAME {
1093 $$ = new PolicyPeering($1);
1094 }
1095 ;
1096
1097 //// action /////////////////////////////////////////////////////////////
1098
1099 opt_action: {
1100 $$ = new PolicyActionList;
1101 }
1102 | KEYW_ACTION action {
1103 $$ = $2;
1104 }
1105 ;
1106
1107 action: single_action {
1108 $$ = new PolicyActionList;
1109 if ($1)
1110 $$->append($1);
1111 }
1112 | action single_action {
1113 $$ = $1;
1114 if ($2)
1115 $$->append($2);
1116 }
1117 ;
1118
1119 single_action: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' ';' {
1120 const AttrMethod *mtd = searchMethod($1, $3, $5);
1121 if (mtd)
1122 $$ = new PolicyAction($1, mtd, $5);
1123 else {
1124 delete $5;
1125 $$ = NULL;
1126 }
1127 free($3);
1128 }
1129 | TKN_RP_ATTR TKN_OPERATOR list_item ';' {
1130 ItemList *plist = new ItemList;
1131 plist->append($3);
1132
1133 const AttrMethod *mtd = searchMethod($1, $2, plist);
1134 if (mtd)
1135 $$ = new PolicyAction($1, mtd, plist);
1136 else {
1137 delete plist;
1138 $$ = NULL;
1139 }
1140 // Added by wlee
1141 free($2);
1142 }
1143 | TKN_RP_ATTR '(' generic_list ')' ';' {
1144 const AttrMethod *mtd = searchMethod($1, "()", $3);
1145 if (mtd)
1146 $$ = new PolicyAction($1, mtd, $3);
1147 else {
1148 delete $3;
1149 $$ = NULL;
1150 }
1151 }
1152 | TKN_RP_ATTR '[' generic_list ']' ';' {
1153 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1154 if (mtd)
1155 $$ = new PolicyAction($1, mtd, $3);
1156 else {
1157 delete $3;
1158 $$ = NULL;
1159 }
1160 }
1161 | ';' {
1162 $$ = NULL;
1163 }
1164 ;
1165
1166 //// filter /////////////////////////////////////////////////////////////
1167
1168 filter: filter OP_OR filter_term {
1169 $$ = new FilterOR($1, $3);
1170 }
1171 | filter filter_term %prec OP_OR {
1172 $$ = new FilterOR($1, $2);
1173 }
1174 | filter_term
1175 ;
1176
1177 filter_term : filter_term OP_AND filter_factor {
1178 $$ = new FilterAND($1, $3);
1179 }
1180 | filter_factor
1181 ;
1182
1183 filter_factor : OP_NOT filter_factor {
1184 $$ = new FilterNOT($2);
1185 }
1186 | '(' filter ')' {
1187 $$ = $2;
1188 }
1189 | filter_operand
1190 ;
1191
1192 filter_operand: KEYW_ANY {
1193 $$ = new FilterANY;
1194 }
1195 | '<' filter_aspath '>' {
1196 $$ = new FilterASPath($2);
1197 }
1198 | filter_rp_attribute {
1199 if ($1)
1200 $$ = $1;
1201 else
1202 $$ = new FilterNOT(new FilterANY);
1203 }
1204 | TKN_FLTRNAME {
1205 $$ = new FilterFLTRNAME($1);
1206 }
1207 | filter_prefix
1208 ;
1209
1210 filter_prefix: filter_prefix_operand OP_MS {
1211 $2->f1 = $1;
1212 $$ = $2;
1213 }
1214 | filter_prefix_operand
1215 ;
1216
1217 filter_prefix_operand: TKN_ASNO {
1218 $$ = new FilterASNO($1);
1219 }
1220 | KEYW_PEERAS {
1221 $$ = new FilterPeerAS;
1222 }
1223 | TKN_ASNAME {
1224 $$ = new FilterASNAME($1);
1225 }
1226 | TKN_RSNAME {
1227 $$ = new FilterRSNAME($1);
1228 }
1229 | '{' opt_filter_prefix_list '}' {
1230 $$ = $2;
1231 }
1232 ;
1233
1234 opt_filter_prefix_list: {
1235 $$ = new FilterPRFXList;
1236 }
1237 | filter_prefix_list
1238 ;
1239
1240 filter_prefix_list: filter_prefix_list_prefix {
1241 ((FilterPRFXList *) ($$ = new FilterPRFXList))->add_high(*$1);
1242 delete $1;
1243 }
1244 | filter_prefix_list ',' filter_prefix_list_prefix {
1245 $$ = $1;
1246 ((FilterPRFXList *) ($$))->add_high(*$3);
1247 delete $3;
1248 }
1249 ;
1250
1251 filter_prefix_list_prefix: TKN_PRFXV4 {
1252 $$ = $1;
1253 }
1254 | TKN_PRFXV4RNG {
1255 $$ = $1;
1256 }
1257 ;
1258
1259 filter_aspath: filter_aspath '|' filter_aspath_term {
1260 $$ = new regexp_or($1, $3);
1261 }
1262 | filter_aspath_term
1263 ;
1264
1265 filter_aspath_term: filter_aspath_term filter_aspath_closure {
1266 $$ = new regexp_cat($1, $2);
1267 }
1268 | filter_aspath_closure
1269 ;
1270
1271 filter_aspath_closure: filter_aspath_closure '*' {
1272 $$ = new regexp_star($1);
1273 }
1274 | filter_aspath_closure '?' {
1275 $$ = new regexp_question($1);
1276 }
1277 | filter_aspath_closure '+' {
1278 $$ = new regexp_plus($1);
1279 }
1280 | filter_aspath_factor
1281 ;
1282
1283 filter_aspath_factor: '^' {
1284 $$ = new regexp_bol;
1285 }
1286 | '$' {
1287 $$ = new regexp_eol;
1288 }
1289 | '(' filter_aspath ')' {
1290 $$ = $2;
1291 }
1292 | filter_aspath_no
1293 ;
1294
1295 filter_aspath_no: TKN_ASNO {
1296 $$ = new regexp_symbol($1);
1297 }
1298 | KEYW_PEERAS {
1299 $$ = new regexp_symbol(symbols.symID("PEERAS"));
1300 }
1301 | TKN_ASNAME {
1302 $$ = new regexp_symbol($1);
1303 }
1304 | '.' {
1305 $$ = new regexp_symbol(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1306 }
1307 | '[' filter_aspath_range ']' {
1308 $$ = $2;
1309 }
1310 | '[' '^' filter_aspath_range ']' {
1311 $$ = $3;
1312 ((regexp_symbol *) $$)->complement();
1313 }
1314 ;
1315
1316 filter_aspath_range: {
1317 $$ = new regexp_symbol;
1318 }
1319 | filter_aspath_range TKN_ASNO {
1320 ((regexp_symbol *) ($$ = $1))->add($2);
1321 }
1322 | filter_aspath_range KEYW_PEERAS {
1323 ((regexp_symbol *) ($$ = $1))->add(symbols.symID("PEERAS"));
1324 }
1325 | filter_aspath_range '.' {
1326 ((regexp_symbol *) ($$ = $1))->add(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1327 }
1328 | filter_aspath_range TKN_ASNO '-' TKN_ASNO {
1329 ((regexp_symbol *) ($$ = $1))->add($2, $4);
1330 }
1331 | filter_aspath_range TKN_ASNAME {
1332 ((regexp_symbol *) ($$ = $1))->add($2);
1333 }
1334 ;
1335
1336 filter_rp_attribute: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' {
1337 const AttrMethod *mtd = searchMethod($1, $3, $5);
1338 if (mtd)
1339 $$ = new FilterRPAttribute($1, mtd, $5);
1340 else {
1341 delete $5;
1342 $$ = NULL;
1343 }
1344 free($3);
1345 }
1346 | TKN_RP_ATTR TKN_OPERATOR list_item {
1347 ItemList *plist = new ItemList;
1348 plist->append($3);
1349
1350 const AttrMethod *mtd = searchMethod($1, $2, plist);
1351 if (mtd)
1352 $$ = new FilterRPAttribute($1, mtd, plist);
1353 else {
1354 delete plist;
1355 $$ = NULL;
1356 }
1357 // Added by wlee
1358 free($2);
1359 }
1360 | TKN_RP_ATTR '(' generic_list ')' {
1361 const AttrMethod *mtd = searchMethod($1, "()", $3);
1362 if (mtd)
1363 $$ = new FilterRPAttribute($1, mtd, $3);
1364 else {
1365 delete $3;
1366 $$ = NULL;
1367 }
1368 }
1369 | TKN_RP_ATTR '[' generic_list ']' {
1370 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1371 if (mtd)
1372 $$ = new FilterRPAttribute($1, mtd, $3);
1373 else {
1374 delete $3;
1375 $$ = NULL;
1376 }
1377 }
1378 ;
1379
1380 //// peering action pair ////////////////////////////////////////////////
1381
1382 import_peering_action_list: KEYW_FROM peering opt_action {
1383 $$ = new List<PolicyPeeringAction>;
1384 $$->append(new PolicyPeeringAction($2, $3));
1385 }
1386 | import_peering_action_list KEYW_FROM peering opt_action {
1387 $$ = $1;
1388 $$->append(new PolicyPeeringAction($3, $4));
1389 }
1390 ;
1391
1392 export_peering_action_list: KEYW_TO peering opt_action {
1393 $$ = new List<PolicyPeeringAction>;
1394 $$->append(new PolicyPeeringAction($2, $3));
1395 }
1396 | export_peering_action_list KEYW_TO peering opt_action {
1397 $$ = $1;
1398 $$->append(new PolicyPeeringAction($3, $4));
1399 }
1400 ;
1401
1402 //// import/export factor ///////////////////////////////////////////////
1403
1404 import_factor: import_peering_action_list KEYW_ACCEPT filter {
1405 $$ = new PolicyFactor($1, $3);
1406 }
1407 ;
1408
1409 import_factor_list: import_factor ';' {
1410 $$ = new PolicyTerm;
1411 $$->append($1);
1412 }
1413 | import_factor_list import_factor ';' {
1414 $$ = $1;
1415 $$->append($2);
1416 }
1417 ;
1418
1419 export_factor: export_peering_action_list KEYW_ANNOUNCE filter {
1420 $$ = new PolicyFactor($1, $3);
1421 }
1422 ;
1423
1424 export_factor_list: export_factor ';' {
1425 $$ = new PolicyTerm;
1426 $$->append($1);
1427 }
1428 | export_factor_list export_factor ';' {
1429 $$ = $1;
1430 $$->append($2);
1431 }
1432 ;
1433
1434 //// import/export term /////////////////////////////////////////////////
1435
1436 import_term: import_factor ';' {
1437 PolicyTerm *term = new PolicyTerm;
1438 term->append($1);
1439 $$ = term;
1440 }
1441 | '{' import_factor_list '}' {
1442 $$ = $2;
1443 }
1444 ;
1445
1446 export_term: export_factor ';' {
1447 PolicyTerm *term = new PolicyTerm;
1448 term->append($1);
1449 $$ = term;
1450 }
1451 | '{' export_factor_list '}' {
1452 $$ = $2;
1453 }
1454 ;
1455
1456 //// import/export expr /////////////////////////////////////////////////
1457
1458 import_expr: import_term {
1459 $$ = $1;
1460 }
1461 | import_term KEYW_REFINE import_expr {
1462 $$ = new PolicyRefine($1, $3);
1463 }
1464 | import_term KEYW_EXCEPT import_expr {
1465 $$ = new PolicyExcept($1, $3);
1466 }
1467 ;
1468
1469 export_expr: export_term {
1470 $$ = $1;
1471 }
1472 | export_term KEYW_REFINE export_expr {
1473 $$ = new PolicyRefine($1, $3);
1474 }
1475 | export_term KEYW_EXCEPT export_expr {
1476 $$ = new PolicyExcept($1, $3);
1477 }
1478 ;
1479
1480 //// protocol ///////////////////////////////////////////////////////////
1481
1482 opt_protocol_from: {
1483 $$ = schema.searchProtocol("BGP4");
1484 }
1485 | KEYW_PROTOCOL tkn_word {
1486 $$ = schema.searchProtocol($2);
1487 if (!$$) {
1488 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1489 $$ = schema.searchProtocol("BGP4");
1490 }
1491 free($2);
1492 }
1493 ;
1494
1495 opt_protocol_into: {
1496 $$ = schema.searchProtocol("BGP4");
1497 }
1498 | KEYW_INTO tkn_word {
1499 $$ = schema.searchProtocol($2);
1500 if (!$$) {
1501 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1502 $$ = schema.searchProtocol("BGP4");
1503 }
1504 free($2);;
1505 }
1506 ;
1507
1508 //**** import/export attributes *******************************************
1509
1510 import_attribute: ATTR_IMPORT
1511 opt_protocol_from opt_protocol_into
1512 import_expr TKN_EOA {
1513 $$ = changeCurrentAttr(new AttrImport($2, $3, $4));
1514 }
1515 | ATTR_IMPORT opt_protocol_from opt_protocol_into import_factor TKN_EOA {
1516 PolicyTerm *term = new PolicyTerm;
1517 term->append($4);
1518
1519 $$ = changeCurrentAttr(new AttrImport($2, $3, term));
1520 }
1521 | ATTR_IMPORT error TKN_EOA {
1522 $$ = $1;
1523 handle_error("Error: from <peering> expected.\n");
1524 yyerrok;
1525 }
1526 ;
1527
1528 export_attribute: ATTR_EXPORT
1529 opt_protocol_from opt_protocol_into
1530 export_expr TKN_EOA {
1531 $$ = changeCurrentAttr(new AttrExport($2, $3, $4));
1532 }
1533 | ATTR_EXPORT opt_protocol_from opt_protocol_into export_factor TKN_EOA {
1534 PolicyTerm *term = new PolicyTerm;
1535 term->append($4);
1536
1537 $$ = changeCurrentAttr(new AttrExport($2, $3, term));
1538 }
1539 | ATTR_EXPORT error TKN_EOA {
1540 $$ = $1;
1541 handle_error("Error: to <peering> expected.\n");
1542 yyerrok;
1543 }
1544 ;
1545
1546 opt_default_filter: {
1547 $$ = new FilterANY;
1548 }
1549 | KEYW_NETWORKS filter {
1550 $$ = $2;
1551 }
1552 ;
1553
1554 default_attribute: ATTR_DEFAULT KEYW_TO peering
1555 opt_action
1556 opt_default_filter TKN_EOA {
1557 $$ = changeCurrentAttr(new AttrDefault($3, $4, $5));
1558 }
1559 | ATTR_DEFAULT KEYW_TO peering error TKN_EOA {
1560 if ($3)
1561 delete $3;
1562 handle_error("Error: badly formed filter/action or keyword NETWORKS/ACTION missing.\n");
1563 yyerrok;
1564 }
1565 | ATTR_DEFAULT error TKN_EOA {
1566 handle_error("Error: TO <peer> missing.\n");
1567 yyerrok;
1568 }
1569 ;
1570
1571 filter_attribute: ATTR_FILTER filter TKN_EOA {
1572 $$ = changeCurrentAttr(new AttrFilter($2));
1573 }
1574 | ATTR_FILTER error TKN_EOA {
1575 $$ = $1;
1576 handle_error("Error: badly formed filter.\n");
1577 yyerrok;
1578 }
1579 ;
1580
1581 peering_attribute: ATTR_PEERING peering TKN_EOA {
1582 $$ = changeCurrentAttr(new AttrPeering($2));
1583 }
1584 | ATTR_PEERING error TKN_EOA {
1585 $$ = $1;
1586 handle_error("Error: badly formed filter.\n");
1587 yyerrok;
1588 }
1589 ;
1590
1591 //**** inet-rtr class *****************************************************
1592
1593 ifaddr_attribute: ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT opt_action TKN_EOA {
1594 $$ = changeCurrentAttr(new AttrIfAddr($2->get_ipaddr(), $4, $5));
1595 delete $2;
1596 }
1597 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT error TKN_EOA {
1598 delete $2;
1599 $$ = $1;
1600 handle_error("Error: in action specification.\n");
1601 yyerrok;
1602 }
1603 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN error TKN_EOA {
1604 delete $2;
1605 $$ = $1;
1606 handle_error("Error: integer mask length expected.\n");
1607 yyerrok;
1608 }
1609 | ATTR_IFADDR TKN_IPV4 error TKN_EOA {
1610 delete $2;
1611 $$ = $1;
1612 handle_error("Error: MASKLEN <length> expected.\n");
1613 yyerrok;
1614 }
1615 | ATTR_IFADDR error TKN_EOA {
1616 $$ = $1;
1617 handle_error("Error: <ip_address> MASKLEN <length> [<action>] expected.\n");
1618 yyerrok;
1619 }
1620 ;
1621
1622 //// peer attribute /////////////////////////////////////////////////////
1623
1624 opt_peer_options: {
1625 $$ = new List<AttrPeerOption>;
1626 }
1627 | peer_options {
1628 $$ = $1;
1629 }
1630 ;
1631
1632 peer_options: peer_option {
1633 $$ = new List<AttrPeerOption>;
1634 $$->append($1);
1635 }
1636 | peer_options ',' peer_option {
1637 $$ = $1;
1638 $$->append($3);
1639 }
1640 ;
1641
1642 peer_option: tkn_word '(' generic_list ')' {
1643 $$ = new AttrPeerOption($1, $3);
1644 }
1645 ;
1646
1647 peer_id: TKN_IPV4
1648 | TKN_DNS {
1649 $$ = new IPAddr;
1650 }
1651 | TKN_RTRSNAME {
1652 $$ = new IPAddr;
1653 }
1654 | TKN_PRNGNAME {
1655 $$ = new IPAddr;
1656 }
1657 ;
1658
1659 peer_attribute: ATTR_PEER tkn_word peer_id opt_peer_options TKN_EOA {
1660 const AttrProtocol *protocol = schema.searchProtocol($2);
1661 int position;
1662 const RPType *correctType;
1663 bool error = false;
1664
1665 if (!protocol) {
1666 handle_error("Error: unknown protocol %s.\n", $2);
1667 error = true;
1668 } else {
1669 ((AttrProtocol *) protocol)->startMandatoryCheck();
1670 for (AttrPeerOption *opt = $4->head(); opt; opt = $4->next(opt)) {
1671 const AttrProtocolOption *decl = protocol->searchOption(opt->option);
1672 if (!decl) {
1673 handle_error("Error: protocol %s does not have option %s.\n",
1674 $2, opt->option);
1675 error = true;
1676 } else {
1677 for (; decl; decl = protocol->searchNextOption(decl))
1678 if (decl->option->validateArgs(opt->args, position, correctType))
1679 break;
1680 if (! decl) {
1681 handleArgumentTypeError($2, opt->option, position, correctType);
1682 error = true;
1683 }
1684 }
1685 }
1686 }
1687
1688 if (! error) {
1689 const AttrProtocolOption *missing =
1690 ((AttrProtocol *) protocol)->missingMandatoryOption();
1691 if (missing) {
1692 handle_error("Error: mandatory option %s of protocol %s is missing.\n",
1693 missing->option->name, $2);
1694 error = true;
1695 }
1696 }
1697
1698 if (!error)
1699 $$ = changeCurrentAttr(new AttrPeer(protocol, $3, $4));
1700 else {
1701 free($2);
1702 delete $3;
1703 delete $4;
1704 }
1705 }
1706 | ATTR_PEER tkn_word TKN_IPV4 error TKN_EOA {
1707 $$ = $1;
1708 free($2);
1709 delete $3;
1710 handle_error("Error: in peer option.\n");
1711 yyerrok;
1712 }
1713 | ATTR_PEER tkn_word error TKN_EOA {
1714 $$ = $1;
1715 free($2);
1716 handle_error("Error: missing peer ip_address.\n");
1717 yyerrok;
1718 }
1719 | ATTR_PEER error TKN_EOA {
1720 $$ = $1;
1721 handle_error("Error: missing protocol name.\n");
1722 yyerrok;
1723 }
1724 ;
1725
1726 //**** route class ********************************************************
1727
1728 aggr_bndry_attribute: ATTR_AGGR_BNDRY as_expr TKN_EOA {
1729 $$ = $1;
1730 delete $2;
1731 }
1732 | ATTR_AGGR_BNDRY error TKN_EOA {
1733 $$ = $1;
1734 handle_error("Error: <as-expression> expected.\n");
1735 yyerrok;
1736 }
1737 ;
1738
1739 aggr_mtd_attribute: ATTR_AGGR_MTD KEYW_INBOUND TKN_EOA {
1740 $$ = $1;
1741 }
1742 | ATTR_AGGR_MTD KEYW_OUTBOUND opt_as_expr TKN_EOA {
1743 delete $3;
1744 }
1745 | ATTR_AGGR_MTD KEYW_OUTBOUND error TKN_EOA {
1746 $$ = $1;
1747 handle_error("Error: OUTBOUND <as-expression> expected.\n");
1748 yyerrok;
1749 }
1750 | ATTR_AGGR_MTD KEYW_INBOUND error TKN_EOA {
1751 $$ = $1;
1752 handle_error("Error: INBOUND can not be followed by anything.\n");
1753 yyerrok;
1754 }
1755 | ATTR_AGGR_MTD error TKN_EOA {
1756 $$ = $1;
1757 handle_error("Error: keyword INBOUND or OUTBOUND expected.\n");
1758 yyerrok;
1759 }
1760 ;
1761
1762 //// inject attribute ///////////////////////////////////////////////////
1763
1764 opt_inject_expr: {
1765 $$ = new FilterANY;
1766 }
1767 | KEYW_UPON inject_expr {
1768 $$ = $2;
1769 }
1770 ;
1771
1772 inject_expr: inject_expr OP_OR inject_expr_term {
1773 $$ = new FilterOR($1, $3);
1774 }
1775 | inject_expr_term
1776 ;
1777
1778 inject_expr_term: inject_expr_term OP_AND inject_expr_factor {
1779 $$ = new FilterAND($1, $3);
1780 }
1781 | inject_expr_factor
1782 ;
1783
1784 inject_expr_factor: '(' inject_expr ')' {
1785 $$ = $2;
1786 }
1787 | inject_expr_operand
1788 ;
1789
1790 inject_expr_operand: KEYW_STATIC {
1791 $$ = new FilterANY;
1792 }
1793 | KEYW_HAVE_COMPONENTS '{' opt_filter_prefix_list '}' {
1794 $$ = new FilterHAVE_COMPONENTS((FilterPRFXList *) $3);
1795 }
1796 | KEYW_EXCLUDE '{' opt_filter_prefix_list '}' {
1797 $$ = new FilterEXCLUDE((FilterPRFXList *) $3);
1798 }
1799 ;
1800
1801 inject_attribute: ATTR_INJECT opt_router_expr_with_at opt_action opt_inject_expr TKN_EOA {
1802 $$ = $1;
1803 delete $2;
1804 delete $3;
1805 delete $4;
1806 }
1807 | ATTR_INJECT error TKN_EOA {
1808 $$ = $1;
1809 handle_error("Error: [at <router-exp>] [action <action>] [upon <condition>] expected.\n");
1810 yyerrok;
1811 }
1812 ;
1813
1814 //// components attribute ///////////////////////////////////////////////
1815
1816 opt_atomic:
1817 | KEYW_ATOMIC
1818 ;
1819
1820 components_list: {
1821 }
1822 | filter {
1823 delete $1;
1824 }
1825 | components_list KEYW_PROTOCOL tkn_word filter {
1826 free($3);
1827 delete $4;
1828 }
1829 ;
1830
1831 components_attribute: ATTR_COMPONENTS opt_atomic components_list TKN_EOA {
1832 $$ = $1;
1833 }
1834 | ATTR_COMPONENTS error TKN_EOA {
1835 $$ = $1;
1836 handle_error("Error: [ATOMIC] [[<filter>] [PROTOCOL <protocol> <filter>] ...] expected.\n");
1837 yyerrok;
1838 }
1839 ;
1840
1841 //**** route-set **********************************************************
1842
1843 opt_rs_members_list: /* empty list */ {
1844 $$ = new ItemList;
1845 }
1846 | rs_members_list
1847 ;
1848
1849 rs_members_list: rs_member {
1850 $$ = new ItemList;
1851 $$->append($1);
1852 }
1853 | rs_members_list ',' rs_member {
1854 $$ = $1;
1855 $$->append($3);
1856 }
1857 ;
1858
1859 rs_member: TKN_ASNO {
1860 $$ = new ItemASNO($1);
1861 }
1862 | TKN_ASNO OP_MS {
1863 $$ = new ItemMSItem(new ItemASNO($1), $2->code, $2->n, $2->m);
1864 delete $2;
1865 }
1866 | TKN_ASNAME {
1867 $$ = new ItemASNAME($1);
1868 }
1869 | TKN_ASNAME OP_MS {
1870 $$ = new ItemMSItem(new ItemASNAME($1), $2->code, $2->n, $2->m);
1871 delete $2;
1872 }
1873 | TKN_RSNAME {
1874 $$ = new ItemRSNAME($1);
1875 }
1876 | TKN_RSNAME OP_MS {
1877 $$ = new ItemMSItem(new ItemRSNAME($1), $2->code, $2->n, $2->m);
1878 delete $2;
1879 }
1880 | TKN_PRFXV4 {
1881 $$ = new ItemPRFXV4($1);
1882 }
1883 | TKN_PRFXV4RNG {
1884 $$ = new ItemPRFXV4Range($1);
1885 }
1886 ;
1887
1888 rs_members_attribute: ATTR_RS_MEMBERS opt_rs_members_list TKN_EOA {
1889 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
1890 }
1891 | ATTR_RS_MEMBERS error TKN_EOA {
1892 $$ = $1;
1893 handle_error("Error: invalid member\n");
1894 yyerrok;
1895 }
1896 ;
1897
1898 //**** dictionary *********************************************************
1899
1900 rpattr_attribute: ATTR_RP_ATTR TKN_WORD methods TKN_EOA {
1901 $$ = changeCurrentAttr(new AttrRPAttr($2, $3));
1902 }
1903 | ATTR_RP_ATTR TKN_RP_ATTR methods TKN_EOA {
1904 $$ = changeCurrentAttr(new AttrRPAttr($2->name, $3));
1905 }
1906 | ATTR_RP_ATTR error TKN_EOA {
1907 $$ = $1;
1908 handle_error("Error: invalid rp-attribute specification\n");
1909 yyerrok;
1910 }
1911 ;
1912
1913 methods: method {
1914 $$ = new List<AttrMethod>;
1915 if ($1)
1916 $$->append($1);
1917 }
1918 | methods method {
1919 $$ = $1;
1920 if ($2)
1921 $$->append($2);
1922 }
1923 ;
1924
1925 method: TKN_WORD '(' ')' {
1926 $$ = new AttrMethod($1, new List<RPTypeNode>, false);
1927 }
1928 | TKN_WORD '(' typedef_type_list ')' {
1929 $$ = new AttrMethod($1, $3, false);
1930 }
1931 | TKN_WORD '(' typedef_type_list ',' TKN_3DOTS ')' {
1932 $$ = new AttrMethod($1, $3, true);
1933 }
1934 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ')' {
1935 char buffer[16];
1936 strcpy(buffer, "operator");
1937 strcat(buffer, $2);
1938 $$ = new AttrMethod(strdup(buffer), $4, false, true);
1939 free($2);
1940 }
1941 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ',' TKN_3DOTS ')' {
1942 char buffer[16];
1943 strcpy(buffer, "operator");
1944 strcat(buffer, $2);
1945 $$ = new AttrMethod(strdup(buffer), $4, true, true);
1946 free($2);
1947 }
1948 | TKN_WORD error ')' {
1949 free($1);
1950 $$ = NULL;
1951 handle_error("Error: invalid method specification for %s\n", $1);
1952 }
1953 | KEYW_OPERATOR TKN_OPERATOR error ')' {
1954 $$ = NULL;
1955 handle_error("Error: invalid operator specification for %s\n", $2);
1956 free($2);
1957 }
1958 | KEYW_OPERATOR error ')' {
1959 $$ = NULL;
1960 handle_error("Error: invalid operator\n");
1961 }
1962 | error ')' {
1963 $$ = NULL;
1964 handle_error("Error: method specification expected\n");
1965 }
1966 ;
1967
1968 //// typedef attribute /////////////////////////////////////////////////
1969
1970 typedef_attribute: ATTR_TYPEDEF TKN_WORD typedef_type TKN_EOA {
1971 $$ = changeCurrentAttr(new AttrTypedef($2, $3));
1972 }
1973 | ATTR_TYPEDEF error TKN_EOA {
1974 $$ = $1;
1975 handle_error("Error: invalid typedef specification\n");
1976 yyerrok;
1977 }
1978 ;
1979
1980 typedef_type_list: typedef_type {
1981 $$ = new List<RPTypeNode>;
1982 if ($1)
1983 $$->append(new RPTypeNode($1));
1984 }
1985 | typedef_type_list ',' typedef_type {
1986 $$ = $1;
1987 if ($3)
1988 $$->append(new RPTypeNode($3));
1989 }
1990 ;
1991
1992 typedef_type: KEYW_UNION typedef_type_list {
1993 $$ = RPType::newRPType("union", $2);
1994 if (!$$) {
1995 handle_error("Error: empty union specification\n");
1996 delete $2;
1997 }
1998 }
1999 | KEYW_RANGE KEYW_OF typedef_type {
2000 if ($3)
2001 $$ = new RPTypeRange($3);
2002 else {
2003 $$ = NULL;
2004 }
2005 }
2006 | TKN_WORD {
2007 $$ = RPType::newRPType($1);
2008 if (!$$) {
2009 handle_error("Error: invalid type %s\n", $1);
2010 }
2011 free($1);
2012 }
2013 | TKN_WORD '[' TKN_INT ',' TKN_INT ']' {
2014 $$ = RPType::newRPType($1, $3, $5);
2015 if (!$$) {
2016 handle_error("Error: invalid type %s[%d,%d]\n", $1, $3, $5);
2017 }
2018 free($1);
2019 }
2020 | TKN_WORD '[' TKN_REAL ',' TKN_REAL ']' {
2021 $$ = RPType::newRPType($1, $3, $5);
2022 if (!$$) {
2023 handle_error("Error: invalid type %s[%f,%f]\n", $1, $3, $5);
2024 }
2025 free($1);
2026 }
2027 | TKN_WORD '[' enum_list ']' {
2028 $$ = RPType::newRPType($1, $3);
2029 if (!$$) {
2030 handle_error("Error: invalid type %s, enum expected\n", $1);
2031 delete $3;
2032 }
2033 free($1);
2034 }
2035 | KEYW_LIST '[' TKN_INT ':' TKN_INT ']' KEYW_OF typedef_type {
2036 if ($8)
2037 if ($3 < $5)
2038 $$ = new RPTypeList($8, $3, $5);
2039 else
2040 $$ = new RPTypeList($8, $5, $3);
2041 else {
2042 $$ = NULL;
2043 delete $8;
2044 }
2045 }
2046 | KEYW_LIST KEYW_OF typedef_type {
2047 if ($3)
2048 $$ = new RPTypeList($3);
2049 else {
2050 $$ = NULL;
2051 }
2052 }
2053 | KEYW_LIST error KEYW_OF typedef_type {
2054 $$ = NULL;
2055 delete $4;
2056 handle_error("Error: invalid list size\n");
2057 }
2058 ;
2059
2060 enum_list: tkn_word {
2061 $$ = new List<WordNode>;
2062 $$->append(new WordNode($1));
2063 }
2064 | enum_list ',' tkn_word {
2065 $$ = $1;
2066 $$->append(new WordNode($3));
2067 }
2068 ;
2069
2070 //// protocol attribute /////////////////////////////////////////////////
2071
2072 protocol_attribute: ATTR_PROTOCOL tkn_word protocol_options TKN_EOA {
2073 $$ = changeCurrentAttr(new AttrProtocol($2, $3));
2074 }
2075 | ATTR_PROTOCOL tkn_word error TKN_EOA {
2076 $$ = $1;
2077 handle_error("Error: invalid protocol option\n");
2078 yyerrok;
2079 }
2080 | ATTR_PROTOCOL error TKN_EOA {
2081 $$ = $1;
2082 handle_error("Error: invalid protocol name\n");
2083 yyerrok;
2084 }
2085 ;
2086
2087 protocol_options: {
2088 $$ = new List<AttrProtocolOption>;
2089 }
2090 | protocol_options protocol_option {
2091 $$ = $1;
2092 $$->append($2);
2093 }
2094 ;
2095
2096 protocol_option: KEYW_MANDATORY method {
2097 $$ = new AttrProtocolOption(false, $2);
2098 }
2099 | KEYW_OPTIONAL method {
2100 $$ = new AttrProtocolOption(true, $2);
2101 }
2102 ;
2103
2104 //**** schema class *******************************************************
2105
2106 opt_attr_options: {
2107 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2108 }
2109 | attr_options {
2110 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2111 *$$ |= *$1;
2112 delete $1;
2113 }
2114 ;
2115
2116 attr_options: attr_option {
2117 $$ = $1;
2118 }
2119 | attr_options ',' attr_option {
2120 $$ = $1;
2121 *$$ |= *$3;
2122 delete $3;
2123 }
2124 | error ',' attr_option {
2125 $$ = $3;
2126 handle_error("Error: in attr option specification.\n");
2127 }
2128 ;
2129
2130 attr_option: KEYW_SYNTAX '(' typedef_type ')' {
2131 $$ = new AttrAttr(ATTR_GENERIC, $3);
2132 }
2133 | KEYW_SYNTAX '(' KEYW_SPECIAL ',' tkn_word ')' {
2134 int syntax = schema.searchAttrSyntax($5);
2135 if (syntax < 0) {
2136 handle_error("Error: no known syntax rule for %s.\n", $5);
2137 $$ = new AttrAttr;
2138 } else
2139 $$ = new AttrAttr(syntax, NULL);
2140 free($5);
2141 }
2142 | KEYW_OPTIONAL {
2143 $$ = new AttrAttr(AttrAttr::OPTIONAL);
2144 }
2145 | KEYW_MANDATORY {
2146 $$ = new AttrAttr;
2147 }
2148 | KEYW_DELETED {
2149 $$ = new AttrAttr(AttrAttr::DELETED)
2150 }
2151 | KEYW_SINGLEVALUED {
2152 $$ = new AttrAttr;
2153 }
2154 | KEYW_MULTIVALUED {
2155 $$ = new AttrAttr(AttrAttr::MULTIVALUED);
2156 }
2157 | KEYW_LOOKUP {
2158 $$ = new AttrAttr(AttrAttr::LOOKUP);
2159 }
2160 | KEYW_KEY {
2161 $$ = new AttrAttr(AttrAttr::KEY);
2162 }
2163 | KEYW_OBSOLETE {
2164 $$ = new AttrAttr(AttrAttr::OBSOLETE);
2165 }
2166 | KEYW_INTERNAL {
2167 $$ = new AttrAttr(AttrAttr::INTERNAL);
2168 }
2169 | KEYW_GENERATED {
2170 $$ = new AttrAttr(AttrAttr::GENERATED);
2171 }
2172 ;
2173
2174 attr_attribute: ATTR_ATTR tkn_word opt_attr_options TKN_EOA {
2175 $3->setName($2);
2176 $$ = changeCurrentAttr($3);
2177 }
2178 | ATTR_ATTR tkn_word error TKN_EOA {
2179 $$ = $1;
2180 free($2);
2181 handle_error("Error: in attr option specification.\n");
2182 yyerrok;
2183 }
2184 | ATTR_ATTR error TKN_EOA {
2185 $$ = $1;
2186 handle_error("Error: attr name expected.\n");
2187 yyerrok;
2188 }
2189 ;
2190
2191 //**** rps-auth stuff *****************************************************
2192
2193 mnt_routes_attribute: ATTR_MNT_ROUTES mnt_routes_list TKN_EOA {
2194 $$ = changeCurrentAttr(new AttrMntRoutes($2));
2195 }
2196 ;
2197
2198 mnt_routes_list: mnt_routes_list_item {
2199 $$ = new List<AttrMntRoutes::MntPrfxPair>;
2200 $$->append($1);
2201 }
2202 | mnt_routes_list ',' mnt_routes_list_item {
2203 $$ = $1;
2204 $$->append($3);
2205 }
2206 ;
2207
2208 mnt_routes_list_item: tkn_word {
2209 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2210 }
2211 | tkn_word KEYW_ANY {
2212 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2213 }
2214 | tkn_word '{' opt_filter_prefix_list '}' {
2215 $$ = new AttrMntRoutes::MntPrfxPair($1, (FilterPRFXList *) $3);
2216 }
2217 ;
2218
2219 %%
2220
2221 void enable_yy_parser_debugging() {
/* [<][>][^][v][top][bottom][index][help] */
2222 #if YYDEBUG != 0
2223 yydebug = 1;
2224 #endif
2225 }
2226
2227 void handleArgumentTypeError(char *attr, char *method, int position,
/* [<][>][^][v][top][bottom][index][help] */
2228 const RPType *correctType,
2229 bool isOperator = false) {
2230 if (isOperator)
2231 if (position)
2232 handle_error("Error: argument %d to %s.operator%s should be %s.\n",
2233 position, attr, method, ((RPType *) correctType)->name());
2234 else
2235 handle_error("Error: wrong number of arguments to %s.operator%s.\n",
2236 attr, method);
2237 else
2238 if (position)
2239 handle_error("Error: argument %d to %s.%s should be %s.\n",
2240 position, attr, method, ((RPType *) correctType)->name());
2241 else
2242 handle_error("Error: wrong number of arguments to %s.%s.\n",
2243 attr, method);
2244 }
2245
2246 const AttrMethod *searchMethod(const AttrRPAttr *rp_attr, char *method, ItemList *args) {
/* [<][>][^][v][top][bottom][index][help] */
2247 const AttrMethod *mtd = rp_attr->searchMethod(method);
2248 int position;
2249 const RPType *correctType;
2250
2251 if (!mtd) {
2252 handle_error("Error: rp-attribute %s does not have %s defined.\n",
2253 rp_attr->name, method);
2254 return NULL;
2255 }
2256
2257 for (; mtd; mtd = rp_attr->searchNextMethod(mtd))
2258 if (mtd->validateArgs(args, position, correctType))
2259 return mtd;
2260
2261 handleArgumentTypeError(rp_attr->name, method, position, correctType);
2262
2263 return NULL;
2264 }