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

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