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

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

## FUNCTIONS

This source file includes following functions.

1. yyparse
2. enable_yy_parser_debugging
3. handleArgumentTypeError
4. searchMethod

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

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