Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | #include <vlib/parse.h> |
| 16 | #include <vlib/unix/unix.h> |
| 17 | |
| 18 | static u8 * format_value_v4_address (u8 * s, va_list * args) |
| 19 | { |
| 20 | vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *); |
| 21 | u32 a = v->value.as_uword; |
| 22 | |
| 23 | s = format (s, "%d.%d.%d.%d", |
| 24 | (a>>24) & 0xFF, |
| 25 | (a>>16) & 0xFF, |
| 26 | (a>>8) & 0xFF, |
| 27 | (a>>0) & 0xFF); |
| 28 | |
| 29 | return s; |
| 30 | } |
| 31 | |
| 32 | static vlib_parse_match_t |
| 33 | v4_address_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, |
| 34 | vlib_lex_token_t *t, vlib_parse_value_t *valuep) |
| 35 | { |
| 36 | u32 digit; |
| 37 | u32 value = 0; |
| 38 | int i; |
| 39 | |
| 40 | if (vec_len (pm->tokens) - (t - pm->tokens) < 7) |
| 41 | return VLIB_PARSE_MATCH_FAIL; |
| 42 | |
| 43 | /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */ |
| 44 | |
| 45 | for (i = 0; i < 7; i++) { |
| 46 | if ((i & 1) == 0) { |
| 47 | if (t[i].token != VLIB_LEX_number) |
| 48 | return VLIB_PARSE_MATCH_FAIL; |
| 49 | if (t[i].value.as_uword > 0xff) |
| 50 | return VLIB_PARSE_MATCH_FAIL; |
| 51 | digit = t[i].value.as_uword; |
| 52 | value = (value << 8) | digit; |
| 53 | } else { |
| 54 | if (t[i].token != VLIB_LEX_dot) |
| 55 | return VLIB_PARSE_MATCH_FAIL; |
| 56 | } |
| 57 | } |
| 58 | /* note: caller advances by 1 */ |
| 59 | pm->current_token_index += 6; |
| 60 | valuep->value.as_uword = value; |
| 61 | return VLIB_PARSE_MATCH_VALUE; |
| 62 | } |
| 63 | |
| 64 | PARSE_TYPE_INIT (v4_address, v4_address_match, 0, format_value_v4_address) |
| 65 | |
| 66 | static u8 * format_value_v4_address_and_mask (u8 * s, va_list * args) |
| 67 | { |
| 68 | vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *); |
| 69 | u32 * a = v->value.as_pointer; |
| 70 | |
| 71 | s = format (s, "%d.%d.%d.%d", |
| 72 | (a[0]>>24) & 0xFF, |
| 73 | (a[0]>>16) & 0xFF, |
| 74 | (a[0]>>8) & 0xFF, |
| 75 | (a[0]>>0) & 0xFF); |
| 76 | s = format (s, "/%d", a[1]); |
| 77 | |
| 78 | return s; |
| 79 | } |
| 80 | |
| 81 | static vlib_parse_match_t |
| 82 | v4_address_and_mask_match (vlib_parse_main_t *pm, vlib_parse_type_t *type, |
| 83 | vlib_lex_token_t *t, vlib_parse_value_t *valuep) |
| 84 | { |
| 85 | u32 digit; |
| 86 | u32 address = 0; |
| 87 | u32 *rv = 0; |
| 88 | int i; |
| 89 | |
| 90 | if (vec_len (pm->tokens) - (t - pm->tokens) < 9) |
| 91 | return VLIB_PARSE_MATCH_FAIL; |
| 92 | |
| 93 | /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */ |
| 94 | |
| 95 | for (i = 0; i < 7; i++) { |
| 96 | if ((i & 1) == 0) { |
| 97 | if (t[i].token != VLIB_LEX_number) |
| 98 | return VLIB_PARSE_MATCH_FAIL; |
| 99 | if (t[i].value.as_uword > 0xff) |
| 100 | return VLIB_PARSE_MATCH_FAIL; |
| 101 | digit = t[i].value.as_uword; |
| 102 | address = (address << 8) | digit; |
| 103 | } else { |
| 104 | if (t[i].token != VLIB_LEX_dot) |
| 105 | return VLIB_PARSE_MATCH_FAIL; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | if (t[7].token != VLIB_LEX_slash || t[8].token != VLIB_LEX_number) |
| 110 | return VLIB_PARSE_MATCH_FAIL; |
| 111 | |
| 112 | vec_add1 (rv, address); |
| 113 | vec_add1 (rv, t[8].value.as_uword); |
| 114 | |
| 115 | /* note: caller advances by 1 */ |
| 116 | pm->current_token_index += 8; |
| 117 | valuep->value.as_pointer = rv; |
| 118 | return VLIB_PARSE_MATCH_VALUE; |
| 119 | } |
| 120 | |
| 121 | void v4_address_and_mask_cleanup (vlib_parse_value_t *valuep) |
| 122 | { |
| 123 | u32 * trash = valuep->value.as_pointer; |
| 124 | vec_free (trash); |
| 125 | } |
| 126 | |
| 127 | PARSE_TYPE_INIT (v4_address_and_mask, v4_address_and_mask_match, |
| 128 | v4_address_and_mask_cleanup, |
| 129 | format_value_v4_address_and_mask) |
| 130 | |
| 131 | vlib_lex_main_t vlib_lex_main; |
| 132 | |
| 133 | |
| 134 | |
| 135 | vlib_parse_match_t eval_factor0 (vlib_parse_main_t *pm, |
| 136 | vlib_parse_item_t *item, |
| 137 | vlib_parse_value_t *value) |
| 138 | { |
| 139 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 140 | return VLIB_PARSE_MATCH_RULE; |
| 141 | } |
| 142 | vlib_parse_match_t eval_factor1 (vlib_parse_main_t *pm, |
| 143 | vlib_parse_item_t *item, |
| 144 | vlib_parse_value_t *value) |
| 145 | { |
| 146 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 147 | return VLIB_PARSE_MATCH_RULE; |
| 148 | } |
| 149 | vlib_parse_match_t eval_factor2 (vlib_parse_main_t *pm, |
| 150 | vlib_parse_item_t *item, |
| 151 | vlib_parse_value_t *value) |
| 152 | { |
| 153 | word a; |
| 154 | int index = vec_len (pm->parse_value)-1; |
| 155 | |
| 156 | a = pm->parse_value [index].value.as_word; |
| 157 | |
| 158 | pm->parse_value[index].value.as_word = -a; |
| 159 | return VLIB_PARSE_MATCH_RULE; |
| 160 | } |
| 161 | vlib_parse_match_t eval_term0 (vlib_parse_main_t *pm, |
| 162 | vlib_parse_item_t *item, |
| 163 | vlib_parse_value_t *value) |
| 164 | { |
| 165 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 166 | return VLIB_PARSE_MATCH_RULE; |
| 167 | } |
| 168 | vlib_parse_match_t eval_term1 (vlib_parse_main_t *pm, |
| 169 | vlib_parse_item_t *item, |
| 170 | vlib_parse_value_t *value) |
| 171 | { |
| 172 | uword a, b; |
| 173 | int index = vec_len (pm->parse_value)-2; |
| 174 | |
| 175 | a = pm->parse_value [index].value.as_uword; |
| 176 | b = pm->parse_value [index+1].value.as_uword; |
| 177 | |
| 178 | pm->parse_value[index].value.as_uword = a * b; |
| 179 | _vec_len (pm->parse_value) -= 1; |
| 180 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 181 | |
| 182 | return VLIB_PARSE_MATCH_RULE; |
| 183 | } |
| 184 | vlib_parse_match_t eval_term2 (vlib_parse_main_t *pm, |
| 185 | vlib_parse_item_t *item, |
| 186 | vlib_parse_value_t *value) |
| 187 | { |
| 188 | uword a, b; |
| 189 | int index = vec_len (pm->parse_value)-2; |
| 190 | |
| 191 | a = pm->parse_value [index].value.as_uword; |
| 192 | b = pm->parse_value [index+1].value.as_uword; |
| 193 | |
| 194 | pm->parse_value[index].value.as_uword = a / b; |
| 195 | _vec_len (pm->parse_value) -= 1; |
| 196 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 197 | |
| 198 | return VLIB_PARSE_MATCH_RULE; |
| 199 | } |
| 200 | vlib_parse_match_t eval_exp0 (vlib_parse_main_t *pm, |
| 201 | vlib_parse_item_t *item, |
| 202 | vlib_parse_value_t *value) |
| 203 | { |
| 204 | return VLIB_PARSE_MATCH_RULE; |
| 205 | } |
| 206 | vlib_parse_match_t eval_exp1 (vlib_parse_main_t *pm, |
| 207 | vlib_parse_item_t *item, |
| 208 | vlib_parse_value_t *value) |
| 209 | { |
| 210 | uword a, b; |
| 211 | int index = vec_len (pm->parse_value)-2; |
| 212 | |
| 213 | a = pm->parse_value [index].value.as_uword; |
| 214 | b = pm->parse_value [index+1].value.as_uword; |
| 215 | |
| 216 | pm->parse_value[index].value.as_uword = a + b; |
| 217 | _vec_len (pm->parse_value) -= 1; |
| 218 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 219 | |
| 220 | return VLIB_PARSE_MATCH_RULE; |
| 221 | } |
| 222 | vlib_parse_match_t eval_exp2 (vlib_parse_main_t *pm, |
| 223 | vlib_parse_item_t *item, |
| 224 | vlib_parse_value_t *value) |
| 225 | { |
| 226 | uword a, b; |
| 227 | int index = vec_len (pm->parse_value)-2; |
| 228 | |
| 229 | a = pm->parse_value [index].value.as_uword; |
| 230 | b = pm->parse_value [index+1].value.as_uword; |
| 231 | |
| 232 | pm->parse_value[index].value.as_uword = a - b; |
| 233 | _vec_len (pm->parse_value) -= 1; |
| 234 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 235 | |
| 236 | return VLIB_PARSE_MATCH_RULE; |
| 237 | } |
| 238 | |
| 239 | vlib_parse_match_t eval_result (vlib_parse_main_t *pm, |
| 240 | vlib_parse_item_t *item, |
| 241 | vlib_parse_value_t *value) |
| 242 | { |
| 243 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 244 | return VLIB_PARSE_MATCH_DONE; |
| 245 | } |
| 246 | |
| 247 | vlib_parse_match_t noop_match_rule (vlib_parse_main_t *pm, |
| 248 | vlib_parse_item_t *item, |
| 249 | vlib_parse_value_t *value) |
| 250 | { |
| 251 | clib_warning ("%U", format_vlib_parse_value, pm); |
| 252 | return VLIB_PARSE_MATCH_RULE; |
| 253 | } |
| 254 | |
| 255 | #if 0 |
| 256 | PARSE_INIT (t1, "moo", eval0); |
| 257 | PARSE_INIT (t2, "moo cow mumble", eval1); |
| 258 | PARSE_INIT (t3, "moo cow", eval2); |
| 259 | PARSE_INIT (t4, "moo cow mumble grunch", eval3); |
| 260 | #endif |
| 261 | |
| 262 | #if 0 |
| 263 | PARSE_INIT (r1, "eval <exp>", eval_result); |
| 264 | |
| 265 | PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0); |
| 266 | PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1); |
| 267 | PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2); |
| 268 | PARSE_INIT (r5, "<exp2> = ", noop_match_rule); |
| 269 | PARSE_TYPE_INIT (exp, rule_match, 0, 0); |
| 270 | PARSE_TYPE_INIT (exp2, rule_match, 0, 0); |
| 271 | |
| 272 | PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0); |
| 273 | PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1); |
| 274 | PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2); |
| 275 | PARSE_INIT (r9, "<term2> = ", noop_match_rule); |
| 276 | PARSE_TYPE_INIT (term, rule_match, 0, 0); |
| 277 | PARSE_TYPE_INIT (term2, rule_match, 0, 0); |
| 278 | |
| 279 | PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1); |
| 280 | PARSE_INIT (r10, "<factor> = <number>", eval_factor0); |
| 281 | PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2); |
| 282 | |
| 283 | PARSE_TYPE_INIT (factor, rule_match, 0, 0); |
| 284 | #endif |
| 285 | |
| 286 | PARSE_INIT (r1, "eval <exp>", eval_result); |
| 287 | |
| 288 | #if 1 |
| 289 | PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0); |
| 290 | PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1); |
| 291 | PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2); |
| 292 | PARSE_INIT (r5, "<exp2> = ", noop_match_rule); |
| 293 | PARSE_TYPE_INIT (exp, rule_match, 0, 0); |
| 294 | PARSE_TYPE_INIT (exp2, rule_match, 0, 0); |
| 295 | |
| 296 | PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0); |
| 297 | PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1); |
| 298 | PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2); |
| 299 | PARSE_INIT (r9, "<term2> = ", noop_match_rule); |
| 300 | PARSE_TYPE_INIT (term, rule_match, 0, 0); |
| 301 | PARSE_TYPE_INIT (term2, rule_match, 0, 0); |
| 302 | |
| 303 | PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1); |
| 304 | PARSE_INIT (r10, "<factor> = <number>", eval_factor0); |
| 305 | PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2); |
| 306 | |
| 307 | PARSE_TYPE_INIT (factor, rule_match, 0, 0); |
| 308 | #endif |
| 309 | |
| 310 | #if 0 |
| 311 | PARSE_TYPE_INIT (exp, rule_match, 0, 0); |
| 312 | PARSE_INIT (r6, "<exp> = a b", eval_term0); |
| 313 | PARSE_INIT (r7, "<exp> = c d", eval_term1); |
| 314 | PARSE_INIT (r9, "<exp> = ", noop_match_rule); |
| 315 | #endif |
| 316 | |
| 317 | #if 0 |
| 318 | #define foreach_rule_evaluator \ |
| 319 | _(0) \ |
| 320 | _(1) \ |
| 321 | _(2) \ |
| 322 | _(3) |
| 323 | |
| 324 | #define _(n) \ |
| 325 | vlib_parse_match_t eval##n (vlib_parse_main_t *pm, \ |
| 326 | vlib_parse_item_t *item, \ |
| 327 | vlib_parse_value_t *value) \ |
| 328 | { \ |
| 329 | clib_warning ("%U", format_vlib_parse_value, pm); \ |
| 330 | return VLIB_PARSE_MATCH_DONE; \ |
| 331 | } |
| 332 | foreach_rule_evaluator |
| 333 | |
| 334 | #undef _ |
| 335 | |
| 336 | PARSE_INIT (r1, "eval <moo>", eval_result); |
| 337 | |
| 338 | PARSE_INIT (r2, "<moo> = cow", eval0); |
| 339 | PARSE_INIT (r4, "<moo> = ", eval1); |
| 340 | PARSE_TYPE_INIT (moo, rule_match, 0, 0); |
| 341 | #endif |
| 342 | |
| 343 | |
| 344 | clib_error_t *test_init (vlib_main_t *vm) |
| 345 | { |
| 346 | clib_error_t *error; |
| 347 | |
| 348 | if ((error = vlib_call_init_function (vm, parse_init))) |
| 349 | return error; |
| 350 | |
| 351 | return 0; |
| 352 | } |
| 353 | |
| 354 | VLIB_INIT_FUNCTION (test_init); |
| 355 | |
| 356 | clib_error_t * |
| 357 | vlib_stdlex_init (vlib_main_t * vm) |
| 358 | { |
| 359 | vlib_lex_main_t * lm = &vlib_lex_main; |
| 360 | u16 top_index; |
| 361 | u16 slash_index, slash_star_index, slash_slash_index, slash_star_star_index; |
| 362 | u16 slash_token; |
| 363 | u16 word_index; |
| 364 | u16 zero_index, octal_index, decimal_index, hex_index, binary_index; |
| 365 | |
| 366 | top_index = vlib_lex_add_table ("top"); |
| 367 | |
| 368 | #define foreach_top_level_single_character_token \ |
| 369 | _('(', lpar) \ |
| 370 | _(')', rpar) \ |
| 371 | _(';', semi) \ |
| 372 | _('[', lbrack) \ |
| 373 | _(']', rbrack) \ |
| 374 | _('{', lcurly) \ |
| 375 | _('}', rcurly) \ |
| 376 | _('+', plus) \ |
| 377 | _('-', minus) \ |
| 378 | _('*', star) \ |
| 379 | _('%', percent) \ |
| 380 | _('@', atsign) \ |
| 381 | _(',', comma) \ |
| 382 | _('.', dot) \ |
| 383 | _('?', qmark) |
| 384 | |
| 385 | #define _(c,t) \ |
| 386 | vlib_lex_set_action_range(top_index,c,c,VLIB_LEX_RETURN,vlib_lex_add_token(lm, #t), top_index); |
| 387 | foreach_top_level_single_character_token; |
| 388 | #undef _ |
| 389 | |
| 390 | /* Numbers */ |
| 391 | zero_index = vlib_lex_add_table ("zero"); |
| 392 | octal_index = vlib_lex_add_table ("octal"); |
| 393 | decimal_index = vlib_lex_add_table ("decimal"); |
| 394 | hex_index = vlib_lex_add_table ("hex"); |
| 395 | binary_index = vlib_lex_add_table ("binary"); |
| 396 | |
| 397 | /* Support 0x 0b 0t and 0123 [octal] */ |
| 398 | vlib_lex_set_action_range (top_index, '0', '0', VLIB_LEX_START_NUMBER, 10, zero_index); |
| 399 | vlib_lex_set_action_range (top_index, '1', '9', VLIB_LEX_START_NUMBER, 10, decimal_index); |
| 400 | |
| 401 | vlib_lex_set_action_range (zero_index, 0, 0x7F, VLIB_LEX_RETURN_AND_RESCAN, VLIB_LEX_number, top_index); |
| 402 | |
| 403 | vlib_lex_set_action_range (zero_index, 'x', 'x', VLIB_LEX_IGNORE, ~0, hex_index); |
| 404 | vlib_lex_set_action_range (zero_index, 'b', 'b', VLIB_LEX_IGNORE, ~0, binary_index); |
| 405 | vlib_lex_set_action_range (zero_index, 't', 't', VLIB_LEX_IGNORE, ~0, decimal_index); |
| 406 | vlib_lex_set_action_range (zero_index, '0', '7', VLIB_LEX_START_NUMBER, 8, octal_index); |
| 407 | |
| 408 | /* Octal */ |
| 409 | vlib_lex_set_action_range (octal_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN, |
| 410 | VLIB_LEX_number, top_index); |
| 411 | vlib_lex_set_action_range (octal_index, '0', '7', VLIB_LEX_ADD_TO_NUMBER, 8, |
| 412 | octal_index); |
| 413 | |
| 414 | /* Decimal */ |
| 415 | vlib_lex_set_action_range (decimal_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN, |
| 416 | VLIB_LEX_number, top_index); |
| 417 | vlib_lex_set_action_range (decimal_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER, 10, |
| 418 | decimal_index); |
| 419 | |
| 420 | /* Hex */ |
| 421 | vlib_lex_set_action_range (hex_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN, |
| 422 | VLIB_LEX_number, top_index); |
| 423 | vlib_lex_set_action_range (hex_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER, 16, |
| 424 | hex_index); |
| 425 | vlib_lex_set_action_range (hex_index, 'a', 'f', VLIB_LEX_ADD_TO_NUMBER, 16, |
| 426 | hex_index); |
| 427 | vlib_lex_set_action_range (hex_index, 'A', 'F', VLIB_LEX_ADD_TO_NUMBER, 16, |
| 428 | hex_index); |
| 429 | |
| 430 | /* Binary */ |
| 431 | vlib_lex_set_action_range (binary_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN, |
| 432 | VLIB_LEX_number, top_index); |
| 433 | vlib_lex_set_action_range (binary_index, '0', '1', VLIB_LEX_ADD_TO_NUMBER, 2, |
| 434 | binary_index); |
| 435 | |
| 436 | /* c/c++ comment syntax is the worst... */ |
| 437 | |
| 438 | slash_index = vlib_lex_add_table ("slash"); |
| 439 | slash_star_index = vlib_lex_add_table ("slash_star"); |
| 440 | slash_star_star_index = vlib_lex_add_table ("slash_star_star"); |
| 441 | slash_slash_index = vlib_lex_add_table ("slash_slash"); |
| 442 | slash_token = vlib_lex_add_token (lm, "slash"); |
| 443 | |
| 444 | /* Top level: see a slash, ignore, go to slash table */ |
| 445 | vlib_lex_set_action_range (top_index, '/', '/', VLIB_LEX_IGNORE, ~0, slash_index); |
| 446 | |
| 447 | /* default for slash table: return SLASH, go to top table */ |
| 448 | vlib_lex_set_action_range (slash_index, 1, 0x7F, VLIB_LEX_RETURN_AND_RESCAN, slash_token, |
| 449 | top_index); |
| 450 | /* see slash-slash, go to s-s table */ |
| 451 | vlib_lex_set_action_range (slash_index, '/', '/', VLIB_LEX_IGNORE, ~0, |
| 452 | slash_slash_index); |
| 453 | /* see slash-star, go to s-* table */ |
| 454 | vlib_lex_set_action_range (slash_index, '*', '*', VLIB_LEX_IGNORE, ~0, |
| 455 | slash_star_index); |
| 456 | |
| 457 | /* EOL in s-s table, ignore, go to top table */ |
| 458 | vlib_lex_set_action_range (slash_slash_index, '\n', '\n', VLIB_LEX_IGNORE, ~0, |
| 459 | top_index); |
| 460 | |
| 461 | /* slash-star blah blah star */ |
| 462 | vlib_lex_set_action_range (slash_star_index, '*', '*', VLIB_LEX_IGNORE, ~0, |
| 463 | slash_star_star_index); |
| 464 | |
| 465 | /* slash star blah blah star slash */ |
| 466 | vlib_lex_set_action_range (slash_star_star_index, '/', '/', VLIB_LEX_IGNORE, ~0, |
| 467 | top_index); |
| 468 | |
| 469 | /* LT, =, GT */ |
| 470 | vlib_lex_set_action_range (top_index, '<', '<', VLIB_LEX_RETURN, VLIB_LEX_lt, top_index); |
| 471 | vlib_lex_set_action_range (top_index, '=', '=', VLIB_LEX_RETURN, VLIB_LEX_equals, |
| 472 | top_index); |
| 473 | vlib_lex_set_action_range (top_index, '>', '>', VLIB_LEX_RETURN, VLIB_LEX_gt, top_index); |
| 474 | |
| 475 | /* words, key and otherwise */ |
| 476 | word_index = vlib_lex_add_table ("word"); |
| 477 | |
| 478 | vlib_lex_set_action_range (top_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 479 | vlib_lex_set_action_range (top_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 480 | |
| 481 | vlib_lex_set_action_range (word_index, 0, 0x7f, VLIB_LEX_KEYWORD_CHECK, ~0, top_index); |
| 482 | |
| 483 | vlib_lex_set_action_range (word_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 484 | vlib_lex_set_action_range (word_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 485 | vlib_lex_set_action_range (word_index, '_', '_', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 486 | vlib_lex_set_action_range (word_index, '0', '9', VLIB_LEX_ADD_TO_TOKEN, ~0, word_index); |
| 487 | |
| 488 | return 0; |
| 489 | } |
| 490 | |