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