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.5 2001/03/16 14:10:31 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 handle_error("Error: argument to %s should be %s.\n",
659 $1->type->name(), $1->type->subsyntax()->name());
660 yyerrok;
661 }
662 ;
663
664 generic_list: /* empty list */ {
665 $$ = new ItemList;
666 }
667 | generic_non_empty_list
668 ;
669
670 generic_non_empty_list: list_item {
671 $$ = new ItemList;
672 $$->append($1);
673 }
674 | generic_non_empty_list ',' list_item {
675 $$ = $1;
676 $$->append($3);
677 }
678 ;
679
680 blobs_attribute: ATTR_BLOBS blobs_list TKN_EOA {
681 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
682 }
683 | ATTR_BLOBS error TKN_EOA {
684 $$ = $1;
685 handle_error("Error: argument to %s should be blob sequence.\n",
686 $1->type->name());
687 yyerrok;
688 }
689 ;
690
691 blobs_list: list_item {
692 $$ = new ItemList;
693 $$->append($1);
694 }
695 | blobs_list list_item {
696 $$ = $1;
697 $$->append($2);
698 }
699 ;
700
701 list_item: list_item_0 {
702 $$ = $1;
703 }
704 | list_item_0 '-' list_item_0 {
705 $$ = new ItemRange($1, $3);
706 }
707 ;
708
709 list_item_0: TKN_ASNO {
710 $$ = new ItemASNO($1);
711 }
712 | TKN_INT {
713 $$ = new ItemINT($1);
714 }
715 | TKN_REAL {
716 $$ = new ItemREAL($1);
717 }
718 | TKN_STRING {
719 $$ = new ItemSTRING($1);
720 }
721 | TKN_TIMESTAMP {
722 $$ = new ItemTimeStamp($1);
723 }
724 | TKN_IPV4 {
725 $$ = new ItemIPV4($1);
726 }
727 | TKN_PRFXV4 {
728 $$ = new ItemPRFXV4($1);
729 }
730 | TKN_PRFXV6 {
731 $$ = new ItemPRFXV6($1);
732 }
733 | TKN_PRFXV4RNG {
734 $$ = new ItemPRFXV4Range($1);
735 }
736 | TKN_IPV4 ':' TKN_INT {
737 $$ = new ItemConnection($1, $3);
738 }
739 | TKN_IPV4 ':' TKN_INT ':' TKN_INT {
740 $$ = new ItemConnection($1, $3, $5);
741 }
742 | TKN_DNS ':' TKN_INT {
743 $$ = new ItemConnection($1, $3);
744 }
745 | TKN_DNS ':' TKN_INT ':' TKN_INT {
746 $$ = new ItemConnection($1, $3, $5);
747 }
748 | TKN_ASNAME {
749 $$ = new ItemASNAME($1);
750 }
751 | TKN_RSNAME {
752 $$ = new ItemRSNAME($1);
753 }
754 | TKN_RTRSNAME {
755 $$ = new ItemRTRSNAME($1);
756 }
757 | TKN_PRNGNAME {
758 $$ = new ItemPRNGNAME($1);
759 }
760 | TKN_FLTRNAME {
761 $$ = new ItemFLTRNAME($1);
762 }
763 | TKN_BOOLEAN {
764 $$ = new ItemBOOLEAN($1);
765 }
766 | TKN_WORD {
767 $$ = new ItemWORD($1);
768 }
769 | tkn_word_from_keyw {
770 $$ = new ItemWORD($1);
771 }
772 | TKN_DNS {
773 $$ = new ItemDNS($1);
774 }
775 | TKN_EMAIL {
776 $$ = new ItemEMAIL($1);
777 }
778 | TKN_KEYCRTNAME {
779 $$ = new ItemKEYCRTNAME($1);
780 }
781 | TKN_BLOB {
782 $$ = new ItemBLOB($1);
783 }
784 | '{' generic_list '}' {
785 $$ = $2;
786 }
787 | '(' filter ')' {
788 $$ = new ItemFilter($2);
789 }
790 ;
791
792 tkn_word: TKN_WORD {
793 $$ = $1;
794 }
795 | TKN_ASNO {
796 char buffer[64];
797 sprintf(buffer, "AS%d", $1);
798 $$ = strdup(buffer);
799 }
800 | TKN_ASNAME {
801 $$ = strdup($1);
802 }
803 | TKN_RSNAME {
804 $$ = strdup($1);
805 }
806 | TKN_RTRSNAME {
807 $$ = strdup($1);
808 }
809 | TKN_PRNGNAME {
810 $$ = strdup($1);
811 }
812 | TKN_FLTRNAME {
813 $$ = strdup($1);
814 }
815 | TKN_NICHDL {
816 $$ = strdup($1);
817 }
818 | TKN_BOOLEAN {
819 if ($1)
820 $$ = strdup("true");
821 else
822 $$ = strdup("false");
823 }
824 | tkn_word_from_keyw
825 | tkn_word_from_keyw_ripe
826 | tkn_word_from_keyw_internic
827 | tkn_word_from_keyw_simple
828 | tkn_word_from_keyw_clientaddress
829 ;
830
831 tkn_word_from_keyw: KEYW_TRUE {
832 $$ = strdup("true");
833 }
834 | KEYW_FALSE {
835 $$ = strdup("false");
836 }
837 | KEYW_ACTION {
838 $$ = strdup("action");
839 }
840 | KEYW_ACCEPT {
841 $$ = strdup("accept");
842 }
843 | KEYW_ANNOUNCE {
844 $$ = strdup("announce");
845 }
846 | KEYW_FROM {
847 $$ = strdup("from");
848 }
849 | KEYW_TO {
850 $$ = strdup("to");
851 }
852 | KEYW_AT {
853 $$ = strdup("at");
854 }
855 | KEYW_ANY {
856 $$ = strdup("any");
857 }
858 | KEYW_REFINE {
859 $$ = strdup("refine");
860 }
861 | KEYW_EXCEPT {
862 $$ = strdup("except");
863 }
864 | KEYW_STATIC {
865 $$ = strdup("static");
866 }
867 | KEYW_NETWORKS {
868 $$ = strdup("networks");
869 }
870 | KEYW_MASKLEN {
871 $$ = strdup("masklen");
872 }
873 | KEYW_UNION {
874 $$ = strdup("union");
875 }
876 | KEYW_RANGE {
877 $$ = strdup("range");
878 }
879 | KEYW_LIST {
880 $$ = strdup("list");
881 }
882 | KEYW_OF {
883 $$ = strdup("of");
884 }
885 | KEYW_OPERATOR {
886 $$ = strdup("operator");
887 }
888 | KEYW_SYNTAX {
889 $$ = strdup("syntax");
890 }
891 | KEYW_SPECIAL {
892 $$ = strdup("special");
893 }
894 | KEYW_OPTIONAL {
895 $$ = strdup("optional");
896 }
897 | KEYW_MANDATORY {
898 $$ = strdup("mandatory");
899 }
900 | KEYW_INTERNAL {
901 $$ = strdup("internal");
902 }
903 | KEYW_DELETED {
904 $$ = strdup("deleted");
905 }
906 | KEYW_SINGLEVALUED {
907 $$ = strdup("singlevalued");
908 }
909 | KEYW_GENERATED {
910 $$ = strdup("generated");
911 }
912 | KEYW_MULTIVALUED {
913 $$ = strdup("multivalued");
914 }
915 | KEYW_LOOKUP {
916 $$ = strdup("lookup");
917 }
918 | KEYW_KEY {
919 $$ = strdup("key");
920 }
921 | KEYW_OBSOLETE {
922 $$ = strdup("obsolete");
923 }
924 | KEYW_PEERAS {
925 $$ = strdup("peeras");
926 }
927 | KEYW_PROTOCOL {
928 $$ = strdup("protocol");
929 }
930 | KEYW_INTO {
931 $$ = strdup("into");
932 }
933 | KEYW_ATOMIC {
934 $$ = strdup("atomic");
935 }
936 | KEYW_INBOUND {
937 $$ = strdup("inbound");
938 }
939 | KEYW_OUTBOUND {
940 $$ = strdup("outbound");
941 }
942 ;
943
944 tkn_word_from_keyw_none: KEYW_NONE {
945 $$ = strdup("none");
946 }
947
948 tkn_word_from_keyw_mailfrom: KEYW_MAILFROM {
949 $$ = strdup("mail-from");
950 }
951
952 tkn_word_from_keyw_cryptpw: KEYW_CRYPTPW {
953 $$ = strdup("crypt-pw");
954 }
955
956 tkn_word_from_keyw_assigned: KEYW_ASSIGNED {
957 $$ = strdup("assigned");
958 }
959
960 tkn_word_from_keyw_allocated: KEYW_ALLOCATED {
961 $$ = strdup("allocated");
962 }
963
964 tkn_word_from_keyw_pi: KEYW_PI {
965 $$ = strdup("pi");
966 }
967
968 tkn_word_from_keyw_pa: KEYW_PA {
969 $$ = strdup("pa");
970 }
971
972 tkn_word_from_keyw_unspecified: KEYW_UNSPECIFIED {
973 $$ = strdup("unspecified");
974 }
975
976 tkn_word_from_keyw_ext: KEYW_EXT {
977 $$ = strdup("ext");
978 }
979
980 tkn_word_from_keyw_simple: KEYW_SIMPLE {
981 $$ = strdup("simple");
982 }
983
984 tkn_word_from_keyw_ripe: KEYW_RIPE {
985 $$ = strdup("ripe");
986 }
987
988 tkn_word_from_keyw_internic: KEYW_INTERNIC {
989 $$ = strdup("internic");
990 }
991
992 tkn_word_from_keyw_clientaddress: KEYW_CLIENTADDRESS {
993 $$ = strdup("clientaddress");
994 }
995
996
997 //**** aut-num class ******************************************************
998
999 //// as_expr ////////////////////////////////////////////////////////////
1000
1001 opt_as_expr: {
1002 $$ = new FilterASNAME(symbols.symID("AS-ANY"));
1003 }
1004 | as_expr
1005 ;
1006
1007 as_expr: as_expr OP_OR as_expr_term {
1008 $$ = new FilterOR($1, $3);
1009 }
1010 | as_expr_term
1011 ;
1012
1013 as_expr_term: as_expr_term OP_AND as_expr_factor {
1014 $$ = new FilterAND($1, $3);
1015 }
1016 | as_expr_term KEYW_EXCEPT as_expr_factor {
1017 $$ = new FilterEXCEPT($1, $3);
1018 }
1019 | as_expr_factor
1020 ;
1021
1022 as_expr_factor: '(' as_expr ')' {
1023 $$ = $2;
1024 }
1025 | as_expr_operand
1026 ;
1027
1028 as_expr_operand: TKN_ASNO {
1029 $$ = new FilterASNO($1);
1030 }
1031 | TKN_ASNAME {
1032 $$ = new FilterASNAME($1);
1033 }
1034 ;
1035
1036 //// router_expr ///////////////////////////////////////////////////////////
1037
1038 opt_router_expr: {
1039 $$ = new FilterANY;
1040 }
1041 | router_expr {
1042 $$ = $1;
1043 }
1044 ;
1045
1046 opt_router_expr_with_at: {
1047 $$ = new FilterANY;
1048 }
1049 | KEYW_AT router_expr {
1050 $$ = $2;
1051 }
1052 ;
1053
1054 router_expr: router_expr OP_OR router_expr_term {
1055 $$ = new FilterOR($1, $3);
1056 }
1057 | router_expr_term
1058 ;
1059
1060 router_expr_term: router_expr_term OP_AND router_expr_factor {
1061 $$ = new FilterAND($1, $3);
1062 }
1063 | router_expr_term KEYW_EXCEPT router_expr_factor {
1064 $$ = new FilterEXCEPT($1, $3);
1065 }
1066 | router_expr_factor
1067 ;
1068
1069 router_expr_factor: '(' router_expr ')' {
1070 $$ = $2;
1071 }
1072 | router_expr_operand
1073 ;
1074
1075 router_expr_operand: TKN_IPV4 {
1076 $$ = new FilterRouter($1);
1077 }
1078 | TKN_DNS {
1079 $$ = new FilterRouterName($1);
1080 }
1081 | TKN_RTRSNAME {
1082 $$ = new FilterRTRSNAME($1);
1083 }
1084 ;
1085
1086 //// peering ////////////////////////////////////////////////////////////
1087
1088 peering: as_expr opt_router_expr opt_router_expr_with_at {
1089 $$ = new PolicyPeering($1, $2, $3);
1090 }
1091 | TKN_PRNGNAME {
1092 $$ = new PolicyPeering($1);
1093 }
1094 ;
1095
1096 //// action /////////////////////////////////////////////////////////////
1097
1098 opt_action: {
1099 $$ = new PolicyActionList;
1100 }
1101 | KEYW_ACTION action {
1102 $$ = $2;
1103 }
1104 ;
1105
1106 action: single_action {
1107 $$ = new PolicyActionList;
1108 if ($1)
1109 $$->append($1);
1110 }
1111 | action single_action {
1112 $$ = $1;
1113 if ($2)
1114 $$->append($2);
1115 }
1116 ;
1117
1118 single_action: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' ';' {
1119 const AttrMethod *mtd = searchMethod($1, $3, $5);
1120 if (mtd)
1121 $$ = new PolicyAction($1, mtd, $5);
1122 else {
1123 delete $5;
1124 $$ = NULL;
1125 }
1126 free($3);
1127 }
1128 | TKN_RP_ATTR TKN_OPERATOR list_item ';' {
1129 ItemList *plist = new ItemList;
1130 plist->append($3);
1131
1132 const AttrMethod *mtd = searchMethod($1, $2, plist);
1133 if (mtd)
1134 $$ = new PolicyAction($1, mtd, plist);
1135 else {
1136 delete plist;
1137 $$ = NULL;
1138 }
1139 // Added by wlee
1140 free($2);
1141 }
1142 | TKN_RP_ATTR '(' generic_list ')' ';' {
1143 const AttrMethod *mtd = searchMethod($1, "()", $3);
1144 if (mtd)
1145 $$ = new PolicyAction($1, mtd, $3);
1146 else {
1147 delete $3;
1148 $$ = NULL;
1149 }
1150 }
1151 | TKN_RP_ATTR '[' generic_list ']' ';' {
1152 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1153 if (mtd)
1154 $$ = new PolicyAction($1, mtd, $3);
1155 else {
1156 delete $3;
1157 $$ = NULL;
1158 }
1159 }
1160 | ';' {
1161 $$ = NULL;
1162 }
1163 ;
1164
1165 //// filter /////////////////////////////////////////////////////////////
1166
1167 filter: filter OP_OR filter_term {
1168 $$ = new FilterOR($1, $3);
1169 }
1170 | filter filter_term %prec OP_OR {
1171 $$ = new FilterOR($1, $2);
1172 }
1173 | filter_term
1174 ;
1175
1176 filter_term : filter_term OP_AND filter_factor {
1177 $$ = new FilterAND($1, $3);
1178 }
1179 | filter_factor
1180 ;
1181
1182 filter_factor : OP_NOT filter_factor {
1183 $$ = new FilterNOT($2);
1184 }
1185 | '(' filter ')' {
1186 $$ = $2;
1187 }
1188 | filter_operand
1189 ;
1190
1191 filter_operand: KEYW_ANY {
1192 $$ = new FilterANY;
1193 }
1194 | '<' filter_aspath '>' {
1195 $$ = new FilterASPath($2);
1196 }
1197 | filter_rp_attribute {
1198 if ($1)
1199 $$ = $1;
1200 else
1201 $$ = new FilterNOT(new FilterANY);
1202 }
1203 | TKN_FLTRNAME {
1204 $$ = new FilterFLTRNAME($1);
1205 }
1206 | filter_prefix
1207 ;
1208
1209 filter_prefix: filter_prefix_operand OP_MS {
1210 $2->f1 = $1;
1211 $$ = $2;
1212 }
1213 | filter_prefix_operand
1214 ;
1215
1216 filter_prefix_operand: TKN_ASNO {
1217 $$ = new FilterASNO($1);
1218 }
1219 | KEYW_PEERAS {
1220 $$ = new FilterPeerAS;
1221 }
1222 | TKN_ASNAME {
1223 $$ = new FilterASNAME($1);
1224 }
1225 | TKN_RSNAME {
1226 $$ = new FilterRSNAME($1);
1227 }
1228 | '{' opt_filter_prefix_list '}' {
1229 $$ = $2;
1230 }
1231 ;
1232
1233 opt_filter_prefix_list: {
1234 $$ = new FilterPRFXList;
1235 }
1236 | filter_prefix_list
1237 ;
1238
1239 filter_prefix_list: filter_prefix_list_prefix {
1240 ((FilterPRFXList *) ($$ = new FilterPRFXList))->add_high(*$1);
1241 delete $1;
1242 }
1243 | filter_prefix_list ',' filter_prefix_list_prefix {
1244 $$ = $1;
1245 ((FilterPRFXList *) ($$))->add_high(*$3);
1246 delete $3;
1247 }
1248 ;
1249
1250 filter_prefix_list_prefix: TKN_PRFXV4 {
1251 $$ = $1;
1252 }
1253 | TKN_PRFXV4RNG {
1254 $$ = $1;
1255 }
1256 ;
1257
1258 filter_aspath: filter_aspath '|' filter_aspath_term {
1259 $$ = new regexp_or($1, $3);
1260 }
1261 | filter_aspath_term
1262 ;
1263
1264 filter_aspath_term: filter_aspath_term filter_aspath_closure {
1265 $$ = new regexp_cat($1, $2);
1266 }
1267 | filter_aspath_closure
1268 ;
1269
1270 filter_aspath_closure: filter_aspath_closure '*' {
1271 $$ = new regexp_star($1);
1272 }
1273 | filter_aspath_closure '?' {
1274 $$ = new regexp_question($1);
1275 }
1276 | filter_aspath_closure '+' {
1277 $$ = new regexp_plus($1);
1278 }
1279 | filter_aspath_factor
1280 ;
1281
1282 filter_aspath_factor: '^' {
1283 $$ = new regexp_bol;
1284 }
1285 | '$' {
1286 $$ = new regexp_eol;
1287 }
1288 | '(' filter_aspath ')' {
1289 $$ = $2;
1290 }
1291 | filter_aspath_no
1292 ;
1293
1294 filter_aspath_no: TKN_ASNO {
1295 $$ = new regexp_symbol($1);
1296 }
1297 | KEYW_PEERAS {
1298 $$ = new regexp_symbol(symbols.symID("PEERAS"));
1299 }
1300 | TKN_ASNAME {
1301 $$ = new regexp_symbol($1);
1302 }
1303 | '.' {
1304 $$ = new regexp_symbol(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1305 }
1306 | '[' filter_aspath_range ']' {
1307 $$ = $2;
1308 }
1309 | '[' '^' filter_aspath_range ']' {
1310 $$ = $3;
1311 ((regexp_symbol *) $$)->complement();
1312 }
1313 ;
1314
1315 filter_aspath_range: {
1316 $$ = new regexp_symbol;
1317 }
1318 | filter_aspath_range TKN_ASNO {
1319 ((regexp_symbol *) ($$ = $1))->add($2);
1320 }
1321 | filter_aspath_range KEYW_PEERAS {
1322 ((regexp_symbol *) ($$ = $1))->add(symbols.symID("PEERAS"));
1323 }
1324 | filter_aspath_range '.' {
1325 ((regexp_symbol *) ($$ = $1))->add(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1326 }
1327 | filter_aspath_range TKN_ASNO '-' TKN_ASNO {
1328 ((regexp_symbol *) ($$ = $1))->add($2, $4);
1329 }
1330 | filter_aspath_range TKN_ASNAME {
1331 ((regexp_symbol *) ($$ = $1))->add($2);
1332 }
1333 ;
1334
1335 filter_rp_attribute: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' {
1336 const AttrMethod *mtd = searchMethod($1, $3, $5);
1337 if (mtd)
1338 $$ = new FilterRPAttribute($1, mtd, $5);
1339 else {
1340 delete $5;
1341 $$ = NULL;
1342 }
1343 free($3);
1344 }
1345 | TKN_RP_ATTR TKN_OPERATOR list_item {
1346 ItemList *plist = new ItemList;
1347 plist->append($3);
1348
1349 const AttrMethod *mtd = searchMethod($1, $2, plist);
1350 if (mtd)
1351 $$ = new FilterRPAttribute($1, mtd, plist);
1352 else {
1353 delete plist;
1354 $$ = NULL;
1355 }
1356 // Added by wlee
1357 free($2);
1358 }
1359 | TKN_RP_ATTR '(' generic_list ')' {
1360 const AttrMethod *mtd = searchMethod($1, "()", $3);
1361 if (mtd)
1362 $$ = new FilterRPAttribute($1, mtd, $3);
1363 else {
1364 delete $3;
1365 $$ = NULL;
1366 }
1367 }
1368 | TKN_RP_ATTR '[' generic_list ']' {
1369 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1370 if (mtd)
1371 $$ = new FilterRPAttribute($1, mtd, $3);
1372 else {
1373 delete $3;
1374 $$ = NULL;
1375 }
1376 }
1377 ;
1378
1379 //// peering action pair ////////////////////////////////////////////////
1380
1381 import_peering_action_list: KEYW_FROM peering opt_action {
1382 $$ = new List<PolicyPeeringAction>;
1383 $$->append(new PolicyPeeringAction($2, $3));
1384 }
1385 | import_peering_action_list KEYW_FROM peering opt_action {
1386 $$ = $1;
1387 $$->append(new PolicyPeeringAction($3, $4));
1388 }
1389 ;
1390
1391 export_peering_action_list: KEYW_TO peering opt_action {
1392 $$ = new List<PolicyPeeringAction>;
1393 $$->append(new PolicyPeeringAction($2, $3));
1394 }
1395 | export_peering_action_list KEYW_TO peering opt_action {
1396 $$ = $1;
1397 $$->append(new PolicyPeeringAction($3, $4));
1398 }
1399 ;
1400
1401 //// import/export factor ///////////////////////////////////////////////
1402
1403 import_factor: import_peering_action_list KEYW_ACCEPT filter {
1404 $$ = new PolicyFactor($1, $3);
1405 }
1406 ;
1407
1408 import_factor_list: import_factor ';' {
1409 $$ = new PolicyTerm;
1410 $$->append($1);
1411 }
1412 | import_factor_list import_factor ';' {
1413 $$ = $1;
1414 $$->append($2);
1415 }
1416 ;
1417
1418 export_factor: export_peering_action_list KEYW_ANNOUNCE filter {
1419 $$ = new PolicyFactor($1, $3);
1420 }
1421 ;
1422
1423 export_factor_list: export_factor ';' {
1424 $$ = new PolicyTerm;
1425 $$->append($1);
1426 }
1427 | export_factor_list export_factor ';' {
1428 $$ = $1;
1429 $$->append($2);
1430 }
1431 ;
1432
1433 //// import/export term /////////////////////////////////////////////////
1434
1435 import_term: import_factor ';' {
1436 PolicyTerm *term = new PolicyTerm;
1437 term->append($1);
1438 $$ = term;
1439 }
1440 | '{' import_factor_list '}' {
1441 $$ = $2;
1442 }
1443 ;
1444
1445 export_term: export_factor ';' {
1446 PolicyTerm *term = new PolicyTerm;
1447 term->append($1);
1448 $$ = term;
1449 }
1450 | '{' export_factor_list '}' {
1451 $$ = $2;
1452 }
1453 ;
1454
1455 //// import/export expr /////////////////////////////////////////////////
1456
1457 import_expr: import_term {
1458 $$ = $1;
1459 }
1460 | import_term KEYW_REFINE import_expr {
1461 $$ = new PolicyRefine($1, $3);
1462 }
1463 | import_term KEYW_EXCEPT import_expr {
1464 $$ = new PolicyExcept($1, $3);
1465 }
1466 ;
1467
1468 export_expr: export_term {
1469 $$ = $1;
1470 }
1471 | export_term KEYW_REFINE export_expr {
1472 $$ = new PolicyRefine($1, $3);
1473 }
1474 | export_term KEYW_EXCEPT export_expr {
1475 $$ = new PolicyExcept($1, $3);
1476 }
1477 ;
1478
1479 //// protocol ///////////////////////////////////////////////////////////
1480
1481 opt_protocol_from: {
1482 $$ = schema.searchProtocol("BGP4");
1483 }
1484 | KEYW_PROTOCOL tkn_word {
1485 $$ = schema.searchProtocol($2);
1486 if (!$$) {
1487 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1488 $$ = schema.searchProtocol("BGP4");
1489 }
1490 free($2);
1491 }
1492 ;
1493
1494 opt_protocol_into: {
1495 $$ = schema.searchProtocol("BGP4");
1496 }
1497 | KEYW_INTO tkn_word {
1498 $$ = schema.searchProtocol($2);
1499 if (!$$) {
1500 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1501 $$ = schema.searchProtocol("BGP4");
1502 }
1503 free($2);;
1504 }
1505 ;
1506
1507 //**** import/export attributes *******************************************
1508
1509 import_attribute: ATTR_IMPORT
1510 opt_protocol_from opt_protocol_into
1511 import_expr TKN_EOA {
1512 $$ = changeCurrentAttr(new AttrImport($2, $3, $4));
1513 }
1514 | ATTR_IMPORT opt_protocol_from opt_protocol_into import_factor TKN_EOA {
1515 PolicyTerm *term = new PolicyTerm;
1516 term->append($4);
1517
1518 $$ = changeCurrentAttr(new AttrImport($2, $3, term));
1519 }
1520 | ATTR_IMPORT error TKN_EOA {
1521 $$ = $1;
1522 handle_error("Error: from <peering> expected.\n");
1523 yyerrok;
1524 }
1525 ;
1526
1527 export_attribute: ATTR_EXPORT
1528 opt_protocol_from opt_protocol_into
1529 export_expr TKN_EOA {
1530 $$ = changeCurrentAttr(new AttrExport($2, $3, $4));
1531 }
1532 | ATTR_EXPORT opt_protocol_from opt_protocol_into export_factor TKN_EOA {
1533 PolicyTerm *term = new PolicyTerm;
1534 term->append($4);
1535
1536 $$ = changeCurrentAttr(new AttrExport($2, $3, term));
1537 }
1538 | ATTR_EXPORT error TKN_EOA {
1539 $$ = $1;
1540 handle_error("Error: to <peering> expected.\n");
1541 yyerrok;
1542 }
1543 ;
1544
1545 opt_default_filter: {
1546 $$ = new FilterANY;
1547 }
1548 | KEYW_NETWORKS filter {
1549 $$ = $2;
1550 }
1551 ;
1552
1553 default_attribute: ATTR_DEFAULT KEYW_TO peering
1554 opt_action
1555 opt_default_filter TKN_EOA {
1556 $$ = changeCurrentAttr(new AttrDefault($3, $4, $5));
1557 }
1558 | ATTR_DEFAULT KEYW_TO peering error TKN_EOA {
1559 if ($3)
1560 delete $3;
1561 handle_error("Error: badly formed filter/action or keyword NETWORKS/ACTION missing.\n");
1562 yyerrok;
1563 }
1564 | ATTR_DEFAULT error TKN_EOA {
1565 handle_error("Error: TO <peer> missing.\n");
1566 yyerrok;
1567 }
1568 ;
1569
1570 filter_attribute: ATTR_FILTER filter TKN_EOA {
1571 $$ = changeCurrentAttr(new AttrFilter($2));
1572 }
1573 | ATTR_FILTER error TKN_EOA {
1574 $$ = $1;
1575 handle_error("Error: badly formed filter.\n");
1576 yyerrok;
1577 }
1578 ;
1579
1580 peering_attribute: ATTR_PEERING peering TKN_EOA {
1581 $$ = changeCurrentAttr(new AttrPeering($2));
1582 }
1583 | ATTR_PEERING error TKN_EOA {
1584 $$ = $1;
1585 handle_error("Error: badly formed filter.\n");
1586 yyerrok;
1587 }
1588 ;
1589
1590 //**** inet-rtr class *****************************************************
1591
1592 ifaddr_attribute: ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT opt_action TKN_EOA {
1593 $$ = changeCurrentAttr(new AttrIfAddr($2->get_ipaddr(), $4, $5));
1594 delete $2;
1595 }
1596 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT error TKN_EOA {
1597 delete $2;
1598 $$ = $1;
1599 handle_error("Error: in action specification.\n");
1600 yyerrok;
1601 }
1602 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN error TKN_EOA {
1603 delete $2;
1604 $$ = $1;
1605 handle_error("Error: integer mask length expected.\n");
1606 yyerrok;
1607 }
1608 | ATTR_IFADDR TKN_IPV4 error TKN_EOA {
1609 delete $2;
1610 $$ = $1;
1611 handle_error("Error: MASKLEN <length> expected.\n");
1612 yyerrok;
1613 }
1614 | ATTR_IFADDR error TKN_EOA {
1615 $$ = $1;
1616 handle_error("Error: <ip_address> MASKLEN <length> [<action>] expected.\n");
1617 yyerrok;
1618 }
1619 ;
1620
1621 //// peer attribute /////////////////////////////////////////////////////
1622
1623 opt_peer_options: {
1624 $$ = new List<AttrPeerOption>;
1625 }
1626 | peer_options {
1627 $$ = $1;
1628 }
1629 ;
1630
1631 peer_options: peer_option {
1632 $$ = new List<AttrPeerOption>;
1633 $$->append($1);
1634 }
1635 | peer_options ',' peer_option {
1636 $$ = $1;
1637 $$->append($3);
1638 }
1639 ;
1640
1641 peer_option: tkn_word '(' generic_list ')' {
1642 $$ = new AttrPeerOption($1, $3);
1643 }
1644 ;
1645
1646 peer_id: TKN_IPV4
1647 | TKN_DNS {
1648 $$ = new IPAddr;
1649 }
1650 | TKN_RTRSNAME {
1651 $$ = new IPAddr;
1652 }
1653 | TKN_PRNGNAME {
1654 $$ = new IPAddr;
1655 }
1656 ;
1657
1658 peer_attribute: ATTR_PEER tkn_word peer_id opt_peer_options TKN_EOA {
1659 const AttrProtocol *protocol = schema.searchProtocol($2);
1660 int position;
1661 const RPType *correctType;
1662 bool error = false;
1663
1664 if (!protocol) {
1665 handle_error("Error: unknown protocol %s.\n", $2);
1666 error = true;
1667 } else {
1668 ((AttrProtocol *) protocol)->startMandatoryCheck();
1669 for (AttrPeerOption *opt = $4->head(); opt; opt = $4->next(opt)) {
1670 const AttrProtocolOption *decl = protocol->searchOption(opt->option);
1671 if (!decl) {
1672 handle_error("Error: protocol %s does not have option %s.\n",
1673 $2, opt->option);
1674 error = true;
1675 } else {
1676 for (; decl; decl = protocol->searchNextOption(decl))
1677 if (decl->option->validateArgs(opt->args, position, correctType))
1678 break;
1679 if (! decl) {
1680 handleArgumentTypeError($2, opt->option, position, correctType);
1681 error = true;
1682 }
1683 }
1684 }
1685 }
1686
1687 if (! error) {
1688 const AttrProtocolOption *missing =
1689 ((AttrProtocol *) protocol)->missingMandatoryOption();
1690 if (missing) {
1691 handle_error("Error: mandatory option %s of protocol %s is missing.\n",
1692 missing->option->name, $2);
1693 error = true;
1694 }
1695 }
1696
1697 if (!error)
1698 $$ = changeCurrentAttr(new AttrPeer(protocol, $3, $4));
1699 else {
1700 free($2);
1701 delete $3;
1702 delete $4;
1703 }
1704 }
1705 | ATTR_PEER tkn_word TKN_IPV4 error TKN_EOA {
1706 $$ = $1;
1707 free($2);
1708 delete $3;
1709 handle_error("Error: in peer option.\n");
1710 yyerrok;
1711 }
1712 | ATTR_PEER tkn_word error TKN_EOA {
1713 $$ = $1;
1714 free($2);
1715 handle_error("Error: missing peer ip_address.\n");
1716 yyerrok;
1717 }
1718 | ATTR_PEER error TKN_EOA {
1719 $$ = $1;
1720 handle_error("Error: missing protocol name.\n");
1721 yyerrok;
1722 }
1723 ;
1724
1725 //**** route class ********************************************************
1726
1727 aggr_bndry_attribute: ATTR_AGGR_BNDRY as_expr TKN_EOA {
1728 $$ = $1;
1729 delete $2;
1730 }
1731 | ATTR_AGGR_BNDRY error TKN_EOA {
1732 $$ = $1;
1733 handle_error("Error: <as-expression> expected.\n");
1734 yyerrok;
1735 }
1736 ;
1737
1738 aggr_mtd_attribute: ATTR_AGGR_MTD KEYW_INBOUND TKN_EOA {
1739 $$ = $1;
1740 }
1741 | ATTR_AGGR_MTD KEYW_OUTBOUND opt_as_expr TKN_EOA {
1742 delete $3;
1743 }
1744 | ATTR_AGGR_MTD KEYW_OUTBOUND error TKN_EOA {
1745 $$ = $1;
1746 handle_error("Error: OUTBOUND <as-expression> expected.\n");
1747 yyerrok;
1748 }
1749 | ATTR_AGGR_MTD KEYW_INBOUND error TKN_EOA {
1750 $$ = $1;
1751 handle_error("Error: INBOUND can not be followed by anything.\n");
1752 yyerrok;
1753 }
1754 | ATTR_AGGR_MTD error TKN_EOA {
1755 $$ = $1;
1756 handle_error("Error: keyword INBOUND or OUTBOUND expected.\n");
1757 yyerrok;
1758 }
1759 ;
1760
1761 //// inject attribute ///////////////////////////////////////////////////
1762
1763 opt_inject_expr: {
1764 $$ = new FilterANY;
1765 }
1766 | KEYW_UPON inject_expr {
1767 $$ = $2;
1768 }
1769 ;
1770
1771 inject_expr: inject_expr OP_OR inject_expr_term {
1772 $$ = new FilterOR($1, $3);
1773 }
1774 | inject_expr_term
1775 ;
1776
1777 inject_expr_term: inject_expr_term OP_AND inject_expr_factor {
1778 $$ = new FilterAND($1, $3);
1779 }
1780 | inject_expr_factor
1781 ;
1782
1783 inject_expr_factor: '(' inject_expr ')' {
1784 $$ = $2;
1785 }
1786 | inject_expr_operand
1787 ;
1788
1789 inject_expr_operand: KEYW_STATIC {
1790 $$ = new FilterANY;
1791 }
1792 | KEYW_HAVE_COMPONENTS '{' opt_filter_prefix_list '}' {
1793 $$ = new FilterHAVE_COMPONENTS((FilterPRFXList *) $3);
1794 }
1795 | KEYW_EXCLUDE '{' opt_filter_prefix_list '}' {
1796 $$ = new FilterEXCLUDE((FilterPRFXList *) $3);
1797 }
1798 ;
1799
1800 inject_attribute: ATTR_INJECT opt_router_expr_with_at opt_action opt_inject_expr TKN_EOA {
1801 $$ = $1;
1802 delete $2;
1803 delete $3;
1804 delete $4;
1805 }
1806 | ATTR_INJECT error TKN_EOA {
1807 $$ = $1;
1808 handle_error("Error: [at <router-exp>] [action <action>] [upon <condition>] expected.\n");
1809 yyerrok;
1810 }
1811 ;
1812
1813 //// components attribute ///////////////////////////////////////////////
1814
1815 opt_atomic:
1816 | KEYW_ATOMIC
1817 ;
1818
1819 components_list: {
1820 }
1821 | filter {
1822 delete $1;
1823 }
1824 | components_list KEYW_PROTOCOL tkn_word filter {
1825 free($3);
1826 delete $4;
1827 }
1828 ;
1829
1830 components_attribute: ATTR_COMPONENTS opt_atomic components_list TKN_EOA {
1831 $$ = $1;
1832 }
1833 | ATTR_COMPONENTS error TKN_EOA {
1834 $$ = $1;
1835 handle_error("Error: [ATOMIC] [[<filter>] [PROTOCOL <protocol> <filter>] ...] expected.\n");
1836 yyerrok;
1837 }
1838 ;
1839
1840 //**** route-set **********************************************************
1841
1842 opt_rs_members_list: /* empty list */ {
1843 $$ = new ItemList;
1844 }
1845 | rs_members_list
1846 ;
1847
1848 rs_members_list: rs_member {
1849 $$ = new ItemList;
1850 $$->append($1);
1851 }
1852 | rs_members_list ',' rs_member {
1853 $$ = $1;
1854 $$->append($3);
1855 }
1856 ;
1857
1858 rs_member: TKN_ASNO {
1859 $$ = new ItemASNO($1);
1860 }
1861 | TKN_ASNO OP_MS {
1862 $$ = new ItemMSItem(new ItemASNO($1), $2->code, $2->n, $2->m);
1863 delete $2;
1864 }
1865 | TKN_ASNAME {
1866 $$ = new ItemASNAME($1);
1867 }
1868 | TKN_ASNAME OP_MS {
1869 $$ = new ItemMSItem(new ItemASNAME($1), $2->code, $2->n, $2->m);
1870 delete $2;
1871 }
1872 | TKN_RSNAME {
1873 $$ = new ItemRSNAME($1);
1874 }
1875 | TKN_RSNAME OP_MS {
1876 $$ = new ItemMSItem(new ItemRSNAME($1), $2->code, $2->n, $2->m);
1877 delete $2;
1878 }
1879 | TKN_PRFXV4 {
1880 $$ = new ItemPRFXV4($1);
1881 }
1882 | TKN_PRFXV4RNG {
1883 $$ = new ItemPRFXV4Range($1);
1884 }
1885 ;
1886
1887 rs_members_attribute: ATTR_RS_MEMBERS opt_rs_members_list TKN_EOA {
1888 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
1889 }
1890 | ATTR_RS_MEMBERS error TKN_EOA {
1891 $$ = $1;
1892 handle_error("Error: invalid member\n");
1893 yyerrok;
1894 }
1895 ;
1896
1897 //**** dictionary *********************************************************
1898
1899 rpattr_attribute: ATTR_RP_ATTR TKN_WORD methods TKN_EOA {
1900 $$ = changeCurrentAttr(new AttrRPAttr($2, $3));
1901 }
1902 | ATTR_RP_ATTR TKN_RP_ATTR methods TKN_EOA {
1903 $$ = changeCurrentAttr(new AttrRPAttr($2->name, $3));
1904 }
1905 | ATTR_RP_ATTR error TKN_EOA {
1906 $$ = $1;
1907 handle_error("Error: invalid rp-attribute specification\n");
1908 yyerrok;
1909 }
1910 ;
1911
1912 methods: method {
1913 $$ = new List<AttrMethod>;
1914 if ($1)
1915 $$->append($1);
1916 }
1917 | methods method {
1918 $$ = $1;
1919 if ($2)
1920 $$->append($2);
1921 }
1922 ;
1923
1924 method: TKN_WORD '(' ')' {
1925 $$ = new AttrMethod($1, new List<RPTypeNode>, false);
1926 }
1927 | TKN_WORD '(' typedef_type_list ')' {
1928 $$ = new AttrMethod($1, $3, false);
1929 }
1930 | TKN_WORD '(' typedef_type_list ',' TKN_3DOTS ')' {
1931 $$ = new AttrMethod($1, $3, true);
1932 }
1933 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ')' {
1934 char buffer[16];
1935 strcpy(buffer, "operator");
1936 strcat(buffer, $2);
1937 $$ = new AttrMethod(strdup(buffer), $4, false, true);
1938 free($2);
1939 }
1940 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ',' TKN_3DOTS ')' {
1941 char buffer[16];
1942 strcpy(buffer, "operator");
1943 strcat(buffer, $2);
1944 $$ = new AttrMethod(strdup(buffer), $4, true, true);
1945 free($2);
1946 }
1947 | TKN_WORD error ')' {
1948 free($1);
1949 $$ = NULL;
1950 handle_error("Error: invalid method specification for %s\n", $1);
1951 }
1952 | KEYW_OPERATOR TKN_OPERATOR error ')' {
1953 $$ = NULL;
1954 handle_error("Error: invalid operator specification for %s\n", $2);
1955 free($2);
1956 }
1957 | KEYW_OPERATOR error ')' {
1958 $$ = NULL;
1959 handle_error("Error: invalid operator\n");
1960 }
1961 | error ')' {
1962 $$ = NULL;
1963 handle_error("Error: method specification expected\n");
1964 }
1965 ;
1966
1967 //// typedef attribute /////////////////////////////////////////////////
1968
1969 typedef_attribute: ATTR_TYPEDEF TKN_WORD typedef_type TKN_EOA {
1970 $$ = changeCurrentAttr(new AttrTypedef($2, $3));
1971 }
1972 | ATTR_TYPEDEF error TKN_EOA {
1973 $$ = $1;
1974 handle_error("Error: invalid typedef specification\n");
1975 yyerrok;
1976 }
1977 ;
1978
1979 typedef_type_list: typedef_type {
1980 $$ = new List<RPTypeNode>;
1981 if ($1)
1982 $$->append(new RPTypeNode($1));
1983 }
1984 | typedef_type_list ',' typedef_type {
1985 $$ = $1;
1986 if ($3)
1987 $$->append(new RPTypeNode($3));
1988 }
1989 ;
1990
1991 typedef_type: KEYW_UNION typedef_type_list {
1992 $$ = RPType::newRPType("union", $2);
1993 if (!$$) {
1994 handle_error("Error: empty union specification\n");
1995 delete $2;
1996 }
1997 }
1998 | KEYW_RANGE KEYW_OF typedef_type {
1999 if ($3)
2000 $$ = new RPTypeRange($3);
2001 else {
2002 $$ = NULL;
2003 }
2004 }
2005 | TKN_WORD {
2006 $$ = RPType::newRPType($1);
2007 if (!$$) {
2008 handle_error("Error: invalid type %s\n", $1);
2009 }
2010 free($1);
2011 }
2012 | TKN_WORD '[' TKN_INT ',' TKN_INT ']' {
2013 $$ = RPType::newRPType($1, $3, $5);
2014 if (!$$) {
2015 handle_error("Error: invalid type %s[%d,%d]\n", $1, $3, $5);
2016 }
2017 free($1);
2018 }
2019 | TKN_WORD '[' TKN_REAL ',' TKN_REAL ']' {
2020 $$ = RPType::newRPType($1, $3, $5);
2021 if (!$$) {
2022 handle_error("Error: invalid type %s[%f,%f]\n", $1, $3, $5);
2023 }
2024 free($1);
2025 }
2026 | TKN_WORD '[' enum_list ']' {
2027 $$ = RPType::newRPType($1, $3);
2028 if (!$$) {
2029 handle_error("Error: invalid type %s, enum expected\n", $1);
2030 delete $3;
2031 }
2032 free($1);
2033 }
2034 | KEYW_LIST '[' TKN_INT ':' TKN_INT ']' KEYW_OF typedef_type {
2035 if ($8)
2036 if ($3 < $5)
2037 $$ = new RPTypeList($8, $3, $5);
2038 else
2039 $$ = new RPTypeList($8, $5, $3);
2040 else {
2041 $$ = NULL;
2042 delete $8;
2043 }
2044 }
2045 | KEYW_LIST KEYW_OF typedef_type {
2046 if ($3)
2047 $$ = new RPTypeList($3);
2048 else {
2049 $$ = NULL;
2050 }
2051 }
2052 | KEYW_LIST error KEYW_OF typedef_type {
2053 $$ = NULL;
2054 delete $4;
2055 handle_error("Error: invalid list size\n");
2056 }
2057 ;
2058
2059 enum_list: tkn_word {
2060 $$ = new List<WordNode>;
2061 $$->append(new WordNode($1));
2062 }
2063 | enum_list ',' tkn_word {
2064 $$ = $1;
2065 $$->append(new WordNode($3));
2066 }
2067 ;
2068
2069 //// protocol attribute /////////////////////////////////////////////////
2070
2071 protocol_attribute: ATTR_PROTOCOL tkn_word protocol_options TKN_EOA {
2072 $$ = changeCurrentAttr(new AttrProtocol($2, $3));
2073 }
2074 | ATTR_PROTOCOL tkn_word error TKN_EOA {
2075 $$ = $1;
2076 handle_error("Error: invalid protocol option\n");
2077 yyerrok;
2078 }
2079 | ATTR_PROTOCOL error TKN_EOA {
2080 $$ = $1;
2081 handle_error("Error: invalid protocol name\n");
2082 yyerrok;
2083 }
2084 ;
2085
2086 protocol_options: {
2087 $$ = new List<AttrProtocolOption>;
2088 }
2089 | protocol_options protocol_option {
2090 $$ = $1;
2091 $$->append($2);
2092 }
2093 ;
2094
2095 protocol_option: KEYW_MANDATORY method {
2096 $$ = new AttrProtocolOption(false, $2);
2097 }
2098 | KEYW_OPTIONAL method {
2099 $$ = new AttrProtocolOption(true, $2);
2100 }
2101 ;
2102
2103 //**** schema class *******************************************************
2104
2105 opt_attr_options: {
2106 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2107 }
2108 | attr_options {
2109 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2110 *$$ |= *$1;
2111 delete $1;
2112 }
2113 ;
2114
2115 attr_options: attr_option {
2116 $$ = $1;
2117 }
2118 | attr_options ',' attr_option {
2119 $$ = $1;
2120 *$$ |= *$3;
2121 delete $3;
2122 }
2123 | error ',' attr_option {
2124 $$ = $3;
2125 handle_error("Error: in attr option specification.\n");
2126 }
2127 ;
2128
2129 attr_option: KEYW_SYNTAX '(' typedef_type ')' {
2130 $$ = new AttrAttr(ATTR_GENERIC, $3);
2131 }
2132 | KEYW_SYNTAX '(' KEYW_SPECIAL ',' tkn_word ')' {
2133 int syntax = schema.searchAttrSyntax($5);
2134 if (syntax < 0) {
2135 handle_error("Error: no known syntax rule for %s.\n", $5);
2136 $$ = new AttrAttr;
2137 } else
2138 $$ = new AttrAttr(syntax, NULL);
2139 free($5);
2140 }
2141 | KEYW_OPTIONAL {
2142 $$ = new AttrAttr(AttrAttr::OPTIONAL);
2143 }
2144 | KEYW_MANDATORY {
2145 $$ = new AttrAttr;
2146 }
2147 | KEYW_DELETED {
2148 $$ = new AttrAttr(AttrAttr::DELETED)
2149 }
2150 | KEYW_SINGLEVALUED {
2151 $$ = new AttrAttr;
2152 }
2153 | KEYW_MULTIVALUED {
2154 $$ = new AttrAttr(AttrAttr::MULTIVALUED);
2155 }
2156 | KEYW_LOOKUP {
2157 $$ = new AttrAttr(AttrAttr::LOOKUP);
2158 }
2159 | KEYW_KEY {
2160 $$ = new AttrAttr(AttrAttr::KEY);
2161 }
2162 | KEYW_OBSOLETE {
2163 $$ = new AttrAttr(AttrAttr::OBSOLETE);
2164 }
2165 | KEYW_INTERNAL {
2166 $$ = new AttrAttr(AttrAttr::INTERNAL);
2167 }
2168 | KEYW_GENERATED {
2169 $$ = new AttrAttr(AttrAttr::GENERATED);
2170 }
2171 ;
2172
2173 attr_attribute: ATTR_ATTR tkn_word opt_attr_options TKN_EOA {
2174 $3->setName($2);
2175 $$ = changeCurrentAttr($3);
2176 }
2177 | ATTR_ATTR tkn_word error TKN_EOA {
2178 $$ = $1;
2179 free($2);
2180 handle_error("Error: in attr option specification.\n");
2181 yyerrok;
2182 }
2183 | ATTR_ATTR error TKN_EOA {
2184 $$ = $1;
2185 handle_error("Error: attr name expected.\n");
2186 yyerrok;
2187 }
2188 ;
2189
2190 //**** rps-auth stuff *****************************************************
2191
2192 mnt_routes_attribute: ATTR_MNT_ROUTES mnt_routes_list TKN_EOA {
2193 $$ = changeCurrentAttr(new AttrMntRoutes($2));
2194 }
2195 ;
2196
2197 mnt_routes_list: mnt_routes_list_item {
2198 $$ = new List<AttrMntRoutes::MntPrfxPair>;
2199 $$->append($1);
2200 }
2201 | mnt_routes_list ',' mnt_routes_list_item {
2202 $$ = $1;
2203 $$->append($3);
2204 }
2205 ;
2206
2207 mnt_routes_list_item: tkn_word {
2208 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2209 }
2210 | tkn_word KEYW_ANY {
2211 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2212 }
2213 | tkn_word '{' opt_filter_prefix_list '}' {
2214 $$ = new AttrMntRoutes::MntPrfxPair($1, (FilterPRFXList *) $3);
2215 }
2216 ;
2217
2218 %%
2219
2220 void enable_yy_parser_debugging() {
/* [<][>][^][v][top][bottom][index][help] */
2221 #if YYDEBUG != 0
2222 yydebug = 1;
2223 #endif
2224 }
2225
2226 void handleArgumentTypeError(char *attr, char *method, int position,
/* [<][>][^][v][top][bottom][index][help] */
2227 const RPType *correctType,
2228 bool isOperator = false) {
2229 if (isOperator)
2230 if (position)
2231 handle_error("Error: argument %d to %s.operator%s should be %s.\n",
2232 position, attr, method, ((RPType *) correctType)->name());
2233 else
2234 handle_error("Error: wrong number of arguments to %s.operator%s.\n",
2235 attr, method);
2236 else
2237 if (position)
2238 handle_error("Error: argument %d to %s.%s should be %s.\n",
2239 position, attr, method, ((RPType *) correctType)->name());
2240 else
2241 handle_error("Error: wrong number of arguments to %s.%s.\n",
2242 attr, method);
2243 }
2244
2245 const AttrMethod *searchMethod(const AttrRPAttr *rp_attr, char *method, ItemList *args) {
/* [<][>][^][v][top][bottom][index][help] */
2246 const AttrMethod *mtd = rp_attr->searchMethod(method);
2247 int position;
2248 const RPType *correctType;
2249
2250 if (!mtd) {
2251 handle_error("Error: rp-attribute %s does not have %s defined.\n",
2252 rp_attr->name, method);
2253 return NULL;
2254 }
2255
2256 for (; mtd; mtd = rp_attr->searchNextMethod(mtd))
2257 if (mtd->validateArgs(args, position, correctType))
2258 return mtd;
2259
2260 handleArgumentTypeError(rp_attr->name, method, position, correctType);
2261
2262 return NULL;
2263 }