modules/rpsl/components.y

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

FUNCTIONS

This source file includes following functions.
  1. yyparse
  2. componentserror
  3. yyerror
  4. syntax_error
  5. yywrap
  6. min
  7. yy_input
  8. main

   1 %{
   2 /*
   3   filename: components.y
   4 
   5   description:
   6     Defines the grammar for an RPSL component attribute.  It was mostly
   7     stolen from the IRRToolSet, simplified by removing ability to parse
   8     things defined by a dictionary (we use XML for extensibility rather
   9     than a dictionary).
  10 
  11   notes:
  12     Defines tokens for the associated lexer, components.l.
  13 */
  14 %}
  15 
  16 %union {
  17     char *sval;
  18 }
  19 
  20 %token OP_OR OP_AND OP_NOT OP_MS OP_EQUAL OP_APPEND OP_COMPARE
  21 %token KEYW_ANY KEYW_PEERAS
  22 %token ASPATH_POSTFIX
  23 %token TKN_FLTRNAME TKN_ASNO TKN_RSNAME TKN_ASNAME TKN_PRFXV4 TKN_PRFXV4RNG
  24 %token KEYW_ATOMIC 
  25 %token KEYW_PROTOCOL TKN_PROTOCOL
  26 %token KEYW_IGP_COST KEYW_SELF KEYW_PREPEND KEYW_APPEND 
  27 %token KEYW_DELETE KEYW_CONTAINS 
  28 %token KEYW_INTERNET KEYW_NO_EXPORT KEYW_NO_ADVERTISE
  29 %token TKN_PREF TKN_MED TKN_DPA TKN_ASPATH TKN_COMMUNITY
  30 %token TKN_NEXT_HOP TKN_COST TKN_COMM_NO TKN_IPV4
  31 
  32 %token <sval> TKN_INT
  33 
  34 %{
  35 #include <stdio.h>
  36 #include <stdarg.h>
  37 #include <stdlib.h>
  38 
  39 int yyerror(const char *s);
  40 
  41 /* defines for unit testing */
  42 #ifdef UNIT_TEST
  43 int main();
  44 #endif /* UNIT_TEST */
  45 %}
  46 
  47 %%
     /* [<][>][^][v][top][bottom][index][help] */
  48 
  49 components: opt_atomic components_list
  50 ;
  51 
  52 opt_atomic:
  53 | KEYW_ATOMIC
  54 ;
  55 
  56 components_list:
  57 | filter
  58 | components_list KEYW_PROTOCOL TKN_PROTOCOL filter
  59 ;
  60 
  61 filter: filter OP_OR filter_term
  62 | filter filter_term %prec OP_OR
  63 | filter_term
  64 ;
  65 
  66 filter_term : filter_term OP_AND filter_factor
  67 | filter_factor
  68 ;
  69 
  70 filter_factor :  OP_NOT filter_factor
  71 | '(' filter ')'
  72 | filter_operand 
  73 ;
  74 
  75 filter_operand: KEYW_ANY
  76 | '<' filter_aspath '>'
  77 | rp_attribute
  78 | TKN_FLTRNAME
  79 | filter_prefix
  80 ;
  81 
  82 filter_prefix: filter_prefix_operand OP_MS
  83 |  filter_prefix_operand
  84 ;
  85 
  86 filter_prefix_operand: TKN_ASNO
  87 | KEYW_PEERAS
  88 | TKN_ASNAME
  89 | TKN_RSNAME
  90 | '{' opt_filter_prefix_list '}'
  91 ;
  92 
  93 opt_filter_prefix_list:
  94 | filter_prefix_list
  95 ;
  96 
  97 filter_prefix_list: filter_prefix_list_prefix 
  98 | filter_prefix_list ',' filter_prefix_list_prefix
  99 ;
 100 
 101 filter_prefix_list_prefix: TKN_PRFXV4
 102 | TKN_PRFXV4RNG
 103 ;
 104 
 105 filter_aspath: filter_aspath '|' filter_aspath_term
 106 | filter_aspath_term
 107 ;
 108 
 109 filter_aspath_term: filter_aspath_term filter_aspath_closure
 110 | filter_aspath_closure
 111 ;
 112 
 113 filter_aspath_closure: filter_aspath_closure '*'
 114 | filter_aspath_closure '?'
 115 | filter_aspath_closure '+'
 116 | filter_aspath_closure ASPATH_POSTFIX
 117 | filter_aspath_factor
 118 ;
 119 
 120 filter_aspath_factor: '^'
 121 | '$'
 122 | '(' filter_aspath ')'
 123 | filter_aspath_no
 124 ;
 125 
 126 filter_aspath_no: TKN_ASNO
 127 | KEYW_PEERAS
 128 | TKN_ASNAME
 129 | '.'
 130 | '[' filter_aspath_range ']'
 131 | '[' '^' filter_aspath_range ']'
 132 ;
 133 
 134 filter_aspath_range:
 135 | filter_aspath_range TKN_ASNO
 136 | filter_aspath_range KEYW_PEERAS
 137 | filter_aspath_range '.'
 138 | filter_aspath_range TKN_ASNO '-' TKN_ASNO
 139 | filter_aspath_range TKN_ASNAME 
 140 ;
 141 
 142 rp_attribute: pref
 143 | med
 144 | dpa
 145 | aspath
 146 | community
 147 | next_hop
 148 | cost
 149 ;
 150 
 151 pref: TKN_PREF OP_EQUAL TKN_INT {
 152       long int val;
 153       char *s, *p;
 154       p = $3;
 155       val = strtol(p, &s, 10);
 156       if ((val < 0) || (val > 65535)) {
 157           syntax_error("pref value \"%s\" is not between 0 and 65535", p);
 158       }
 159 }
 160 ;
 161 
 162 med: TKN_MED OP_EQUAL TKN_INT {
 163       long int val;
 164       char *s, *p;
 165       p = $3;
 166       val = strtol(p, &s, 10);
 167       if ((val < 0) || (val > 65535)) {
 168           syntax_error("med value \"%s\" is not between 0 and 65535", p);
 169       }
 170 }
 171 | TKN_MED OP_EQUAL KEYW_IGP_COST
 172 ;
 173 
 174 dpa: TKN_DPA OP_EQUAL TKN_INT {
 175       long int val;
 176       char *s, *p;
 177       p = $3;
 178       val = strtol(p, &s, 10);
 179       if ((val < 0) || (val > 65535)) {
 180           syntax_error("dpa value \"%s\" is not between 0 and 65535", p);
 181       }
 182 }
 183 ;
 184 
 185 aspath: TKN_ASPATH '.' KEYW_PREPEND '(' asno_list ')'
 186 ;
 187 
 188 asno_list: TKN_ASNO
 189 | asno_list ',' TKN_ASNO
 190 ;
 191 
 192 community: TKN_COMMUNITY OP_EQUAL community_list
 193 | TKN_COMMUNITY OP_APPEND community_list
 194 | TKN_COMMUNITY '.' KEYW_APPEND '(' community_elm_list ')'
 195 | TKN_COMMUNITY '.' KEYW_DELETE '(' community_elm_list ')'
 196 | TKN_COMMUNITY '.' KEYW_CONTAINS '(' community_elm_list ')'
 197 | TKN_COMMUNITY '(' community_elm_list ')'
 198 | TKN_COMMUNITY OP_COMPARE community_list
 199 ;
 200 
 201 community_list: '{' community_elm_list '}'
 202 ;
 203 
 204 community_elm_list: community_elm
 205 | community_elm_list ',' community_elm
 206 ;
 207 
 208 community_elm: KEYW_INTERNET
 209 | KEYW_NO_EXPORT
 210 | KEYW_NO_ADVERTISE
 211 | TKN_INT {
 212       unsigned long int val;
 213       char *s, *p;
 214       p = $1;
 215       val = strtoul(p, &s, 10);
 216       if ((val < 1) || (val > 4294967295UL) || (*s != '\0')) {
 217           syntax_error("community element \"%s\" is not between 1 and 4294967295",
 218                        p);
 219       }
 220 }
 221 | TKN_COMM_NO
 222 ;
 223 
 224 next_hop: TKN_NEXT_HOP OP_EQUAL TKN_IPV4
 225 | TKN_NEXT_HOP OP_EQUAL KEYW_SELF
 226 ;
 227 
 228 cost: TKN_COST OP_EQUAL TKN_INT {
 229       long int val;
 230       char *s, *p;
 231       p = $3;
 232       val = strtol(p, &s, 10);
 233       if ((val < 0) || (val > 65535)) {
 234           syntax_error("cost value \"%s\" is not between 0 and 65535", p);
 235       }
 236 }
 237 ;
 238 
 239 %%
 240 
 241 /* define a unit test that simply returns "yes" or "no" for filter input */
 242 #ifndef UNIT_TEST
 243 
 244 #undef componentserror
 245 #undef yyerror
 246 
 247 int
 248 componentserror (const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 249 {
 250     yyerror(s);
 251     return 0;
 252 }
 253 #else /* UNIT_TEST */
 254 
 255 int parse_error_count;
 256 
 257 /* parse error */
 258 void 
 259 yyerror(const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 260 {
 261     fputs(s, stderr);
 262     putc('\n', stderr);
 263     parse_error_count++;
 264 }
 265 
 266 /* syntax error */
 267 void 
 268 syntax_error(const char *fmt, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 269 {
 270     va_list args;
 271     char buf[1024];
 272 
 273     va_start(args, fmt);
 274     vsnprintf(buf, sizeof(buf), fmt, args);
 275     va_end(args);
 276     yyerror(buf);
 277 }
 278 
 279 int
 280 yywrap()
     /* [<][>][^][v][top][bottom][index][help] */
 281 {
 282     return 1;
 283 }
 284 
 285 /* taken from _lex & yacc_ p.157, by Levine, Mason, & Brown (corrected) */
 286 char *myinputptr;
 287 char *myinputlim;
 288 
 289 #undef min
 290 #define min(a, b)  (((a) < (b)) ? (a) : (b))
     /* [<][>][^][v][top][bottom][index][help] */
 291 
 292 void
 293 yy_input(char *buf, int *result, int max_size)
     /* [<][>][^][v][top][bottom][index][help] */
 294 {
 295     int n = min(max_size, myinputlim - myinputptr);
 296 
 297     if (n > 0) {
 298         memcpy(buf, myinputptr, n);
 299         myinputptr += n;
 300     }
 301     *result = n;
 302 }
 303 
 304 /* program entry point */
 305 int 
 306 main()
     /* [<][>][^][v][top][bottom][index][help] */
 307 {
 308     char buf[4096];
 309 
 310     setbuf(stdout, NULL);
 311     for (;;) {
 312         printf("filter> ");
 313         if (gets(buf) == NULL) {
 314             printf("\n");
 315             return(0);
 316         }
 317         parse_error_count = 0;
 318         myinputptr = buf;
 319         myinputlim = buf + strlen(buf);
 320         filterparse();
 321         printf("%d parse errors\n", parse_error_count);
 322     }
 323 }
 324 #endif /* UNIT_TEST */

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