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

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