## 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] */