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

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