modules/up/src/rpsl/rpsl/rpsl.y

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. yyparse
  2. enable_yy_parser_debugging
  3. handleArgumentTypeError
  4. searchMethod

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

/* [<][>][^][v][top][bottom][index][help] */