1/* 2 * Copyright (c) 2015 PLUMgrid, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17%skeleton "lalr1.cc" 18%defines 19%define namespace "ebpf::cc" 20%define parser_class_name "BisonParser" 21%parse-param { ebpf::cc::Lexer &lexer } 22%parse-param { ebpf::cc::Parser &parser } 23%lex-param { ebpf::cc::Lexer &lexer } 24%locations 25 26%code requires { 27 #include <memory> 28 #include <vector> 29 #include <string> 30 #include "node.h" 31 // forward declaration 32 namespace ebpf { namespace cc { 33 class Lexer; 34 class Parser; 35 } } 36} 37 38%code { 39 static int yylex(ebpf::cc::BisonParser::semantic_type *yylval, 40 ebpf::cc::BisonParser::location_type *yylloc, 41 ebpf::cc::Lexer &lexer); 42} 43 44%{ 45 #include "node.h" 46 #include "parser.h" 47 using std::unique_ptr; 48 using std::vector; 49 using std::string; 50 using std::move; 51%} 52 53%union { 54 Scopes::StateScope *state_scope; 55 Scopes::VarScope *var_scope; 56 BlockStmtNode *block; 57 ExprNode *expr; 58 MethodCallExprNode *call; 59 StmtNode *stmt; 60 IdentExprNode *ident; 61 IntegerExprNode *numeric; 62 BitopExprNode *bitop; 63 ExprNodeList *args; 64 IdentExprNodeList *ident_args; 65 StmtNodeList *stmts; 66 FormalList *formals; 67 VariableDeclStmtNode *decl; 68 StructVariableDeclStmtNode *type_decl; 69 TableIndexExprNode *table_index; 70 std::vector<int> *type_specifiers; 71 std::string* string; 72 int token; 73} 74 75/* Define the terminal symbols. */ 76%token <string> TIDENTIFIER TINTEGER THEXINTEGER TPRAGMA TSTRING 77%token <token> TU8 TU16 TU32 TU64 78%token <token> TEQUAL TCEQ TCNE TCLT TCLE TCGT TCGE TAND TOR 79%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TLBRACK TRBRACK 80%token <token> TDOT TARROW TCOMMA TPLUS TMINUS TMUL TDIV TMOD TXOR TDOLLAR TCOLON TSCOPE TNOT TSEMI TCMPL TLAND TLOR 81%token <token> TSTRUCT TSTATE TFUNC TGOTO TCONTINUE TNEXT TTRUE TFALSE TRETURN 82%token <token> TIF TELSE TSWITCH TCASE 83%token <token> TMATCH TMISS TFAILURE TVALID 84%token <token> TAT 85 86/* Define non-terminal symbols as defined in the above union */ 87%type <ident> ident scoped_ident dotted_ident any_ident 88%type <expr> expr assign_expr return_expr init_arg_kv 89%type <numeric> numeric 90%type <bitop> bitop 91%type <args> call_args /*init_args*/ init_args_kv 92%type <ident_args> table_decl_args 93%type <formals> struct_decl_stmts formals 94%type <block> program block prog_decls 95%type <decl> decl_stmt int_decl ref_stmt 96%type <type_decl> type_decl ptr_decl 97%type <stmt> stmt prog_decl var_decl struct_decl state_decl func_decl 98%type <stmt> table_decl table_result_stmt if_stmt switch_stmt case_stmt onvalid_stmt 99%type <var_scope> enter_varscope exit_varscope 100%type <state_scope> enter_statescope exit_statescope 101%type <stmts> stmts table_result_stmts case_stmts 102%type <call> call_expr 103%type <table_index> table_index_expr 104%type <type_specifiers> type_specifiers 105%type <stmt> pragma_decl 106%type <token> type_specifier 107 108/* taken from C++ operator precedence wiki page */ 109%nonassoc TSCOPE 110%left TDOT TLBRACK TLBRACE TLPAREN TINCR TDECR 111%right TNOT TCMPL 112%left TMUL 113%left TDIV 114%left TMOD 115%left TPLUS 116%left TMINUS 117%left TCLT TCLE TCGT TCGE 118%left TCEQ 119%left TCNE 120%left TXOR 121%left TAND 122%left TOR 123%left TLAND 124%left TLOR 125%right TEQUAL 126 127%start program 128 129%% 130 131program 132 : enter_statescope enter_varscope prog_decls exit_varscope exit_statescope 133 { parser.root_node_ = $3; $3->scope_ = $2; } 134 ; 135 136/* program is a list of declarations */ 137prog_decls 138 : prog_decl 139 { $$ = new BlockStmtNode; $$->stmts_.push_back(StmtNode::Ptr($1)); } 140 | prog_decls prog_decl 141 { $1->stmts_.push_back(StmtNode::Ptr($2)); } 142 ; 143 144/* 145 possible program declarations are: 146 "struct {}" 147 "state|on_miss|on_match|on_valid {}" 148 "var <var_decl>" 149 "Table <...> <ident>(size)" 150 */ 151prog_decl 152 : var_decl TSEMI 153 | struct_decl TSEMI 154 | state_decl 155 | table_decl TSEMI 156 | pragma_decl 157 | func_decl 158 ; 159 160pragma_decl 161 : TPRAGMA TIDENTIFIER TIDENTIFIER 162 { $$ = new BlockStmtNode; parser.add_pragma(*$2, *$3); delete $2; delete $3; } 163 | TPRAGMA TIDENTIFIER TSTRING 164 { $$ = new BlockStmtNode; parser.add_pragma(*$2, *$3); delete $2; delete $3; } 165 ; 166 167stmts 168 : stmt 169 { $$ = new StmtNodeList; $$->push_back(StmtNode::Ptr($1)); } 170 | stmts stmt 171 { $1->push_back(StmtNode::Ptr($2)); } 172 ; 173 174stmt 175 : expr TSEMI 176 { $$ = new ExprStmtNode(ExprNode::Ptr($1)); 177 parser.set_loc($$, @$); } 178 | assign_expr TSEMI 179 { $$ = new ExprStmtNode(ExprNode::Ptr($1)); 180 parser.set_loc($$, @$); } 181 | return_expr TSEMI 182 { $$ = new ExprStmtNode(ExprNode::Ptr($1)); 183 parser.set_loc($$, @$); } 184 | call_expr TLBRACE enter_varscope table_result_stmts exit_varscope TRBRACE TSEMI 185 { $$ = new ExprStmtNode(ExprNode::Ptr($1)); 186 $1->block_->stmts_ = move(*$4); delete $4; 187 $1->block_->scope_ = $3; 188 parser.set_loc($$, @$); } 189 | call_expr TLBRACE TRBRACE TSEMI // support empty curly braces 190 { $$ = new ExprStmtNode(ExprNode::Ptr($1)); 191 parser.set_loc($$, @$); } 192 | if_stmt 193 | switch_stmt 194 | var_decl TSEMI 195 { $$ = $1; } 196 | state_decl 197 | onvalid_stmt 198 ; 199 200call_expr 201 : any_ident TLPAREN call_args TRPAREN 202 { $$ = new MethodCallExprNode(IdentExprNode::Ptr($1), move(*$3), lexer.lineno()); delete $3; 203 parser.set_loc($$, @$); } 204 ; 205 206block 207 : TLBRACE stmts TRBRACE 208 { $$ = new BlockStmtNode; $$->stmts_ = move(*$2); delete $2; 209 parser.set_loc($$, @$); } 210 | TLBRACE TRBRACE 211 { $$ = new BlockStmtNode; 212 parser.set_loc($$, @$); } 213 ; 214 215enter_varscope : /* empty */ { $$ = parser.scopes_->enter_var_scope(); } ; 216exit_varscope : /* emtpy */ { $$ = parser.scopes_->exit_var_scope(); } ; 217enter_statescope : /* empty */ { $$ = parser.scopes_->enter_state_scope(); } ; 218exit_statescope : /* emtpy */ { $$ = parser.scopes_->exit_state_scope(); } ; 219 220struct_decl 221 : TSTRUCT ident TLBRACE struct_decl_stmts TRBRACE 222 { $$ = parser.struct_add($2, $4); delete $4; 223 parser.set_loc($$, @$); } 224 ; 225 226struct_decl_stmts 227 : type_specifiers decl_stmt TSEMI 228 { $$ = new FormalList; $$->push_back(VariableDeclStmtNode::Ptr($2)); } 229 | struct_decl_stmts type_specifiers decl_stmt TSEMI 230 { $1->push_back(VariableDeclStmtNode::Ptr($3)); } 231 ; 232 233table_decl 234 : ident TCLT table_decl_args TCGT ident TLPAREN TINTEGER TRPAREN 235 { $$ = parser.table_add($1, $3, $5, $7); delete $3; 236 parser.set_loc($$, @$); } 237 ; 238 239table_decl_args 240 : ident 241 { $$ = new IdentExprNodeList; $$->push_back(IdentExprNode::Ptr($1)); } 242 | table_decl_args TCOMMA ident 243 { $$->push_back(IdentExprNode::Ptr($3)); } 244 ; 245 246state_decl 247 : TSTATE scoped_ident enter_statescope enter_varscope block exit_varscope exit_statescope 248 { $$ = parser.state_add($3, $2, $5); $5->scope_ = $4; 249 if (!$$) YYERROR; 250 parser.set_loc($$, @$); } 251 | TSTATE scoped_ident TCOMMA TMUL enter_statescope enter_varscope block exit_varscope exit_statescope 252 { $$ = parser.state_add($5, $2, new IdentExprNode(""), $7); $7->scope_ = $6; 253 if (!$$) YYERROR; 254 parser.set_loc($$, @$); } 255 | TSTATE scoped_ident TCOMMA scoped_ident enter_statescope enter_varscope block exit_varscope exit_statescope 256 { $$ = parser.state_add($5, $2, $4, $7); $7->scope_ = $6; 257 if (!$$) YYERROR; 258 parser.set_loc($$, @$); } 259 ; 260 261func_decl 262 : type_specifiers ident enter_statescope enter_varscope TLPAREN formals TRPAREN block exit_varscope exit_statescope 263 { $$ = parser.func_add($1, $3, $2, $6, $8); $8->scope_ = $4; 264 if (!$$) YYERROR; 265 parser.set_loc($$, @$); } 266 ; 267 268table_result_stmts 269 : table_result_stmt 270 { $$ = new StmtNodeList; $$->push_back(StmtNode::Ptr($1)); } 271 | table_result_stmts table_result_stmt 272 { $$->push_back(StmtNode::Ptr($2)); } 273 ; 274 275table_result_stmt 276 : TMATCH ident enter_varscope TLPAREN formals TRPAREN block exit_varscope TSEMI 277 { $$ = parser.result_add($1, $2, $5, $7); delete $5; $7->scope_ = $3; 278 if (!$$) YYERROR; 279 parser.set_loc($$, @$); } 280 | TMISS ident enter_varscope TLPAREN TRPAREN block exit_varscope TSEMI 281 { $$ = parser.result_add($1, $2, new FormalList, $6); $6->scope_ = $3; 282 if (!$$) YYERROR; 283 parser.set_loc($$, @$); } 284 | TFAILURE ident enter_varscope TLPAREN formals TRPAREN block exit_varscope TSEMI 285 { $$ = parser.result_add($1, $2, $5, $7); delete $5; $7->scope_ = $3; 286 if (!$$) YYERROR; 287 parser.set_loc($$, @$); } 288 ; 289 290formals 291 : TSTRUCT ptr_decl 292 { $$ = new FormalList; $$->push_back(VariableDeclStmtNode::Ptr(parser.variable_add(nullptr, $2))); } 293 | formals TCOMMA TSTRUCT ptr_decl 294 { $1->push_back(VariableDeclStmtNode::Ptr(parser.variable_add(nullptr, $4))); } 295 ; 296 297type_specifier 298 : TU8 299 | TU16 300 | TU32 301 | TU64 302 ; 303 304type_specifiers 305 : type_specifier { $$ = new std::vector<int>; $$->push_back($1); } 306 | type_specifiers type_specifier { $$->push_back($2); } 307 ; 308 309var_decl 310 : type_specifiers decl_stmt 311 { $$ = parser.variable_add($1, $2); 312 if (!$$) YYERROR; 313 parser.set_loc($$, @$); } 314 | type_specifiers int_decl TEQUAL expr 315 { $$ = parser.variable_add($1, $2, $4); 316 if (!$$) YYERROR; 317 parser.set_loc($$, @$); } 318 | TSTRUCT type_decl TEQUAL TLBRACE init_args_kv TRBRACE 319 { $$ = parser.variable_add($2, $5, true); 320 if (!$$) YYERROR; 321 parser.set_loc($$, @$); } 322 /*| TSTRUCT type_decl TEQUAL TLBRACE init_args TRBRACE 323 { $$ = parser.variable_add($2, $5, false); 324 parser.set_loc($$, @$); }*/ 325 | TSTRUCT ref_stmt 326 { $$ = parser.variable_add(nullptr, $2); 327 if (!$$) YYERROR; 328 parser.set_loc($$, @$); } 329 ; 330 331/* "id":"bitsize" or "type" "id" */ 332decl_stmt : int_decl { $$ = $1; } | type_decl { $$ = $1; }; 333int_decl : ident TCOLON TINTEGER 334 { $$ = new IntegerVariableDeclStmtNode(IdentExprNode::Ptr($1), *$3); delete $3; 335 parser.set_loc($$, @$); } 336 ; 337 338type_decl : scoped_ident ident 339 { $$ = new StructVariableDeclStmtNode(IdentExprNode::Ptr($1), IdentExprNode::Ptr($2)); 340 parser.set_loc($$, @$); } 341 ; 342 343/* "type" "*" "id" */ 344ref_stmt : ptr_decl { $$ = $1; }; 345ptr_decl : scoped_ident TMUL ident 346 { $$ = new StructVariableDeclStmtNode(IdentExprNode::Ptr($1), IdentExprNode::Ptr($3), 347 VariableDeclStmtNode::STRUCT_REFERENCE); 348 parser.set_loc($$, @$); } 349 ; 350 351/* normal initializer */ 352/* init_args 353 : expr { $$ = new ExprNodeList; $$->push_back(ExprNode::Ptr($1)); } 354 | init_args TCOMMA expr { $$->push_back(ExprNode::Ptr($3)); } 355 ;*/ 356 357/* one or more of "field" = "expr" */ 358init_args_kv 359 : init_arg_kv { $$ = new ExprNodeList; $$->push_back(ExprNode::Ptr($1)); } 360 | init_args_kv TCOMMA init_arg_kv { $$->push_back(ExprNode::Ptr($3)); } 361 ; 362init_arg_kv 363 : TDOT ident TEQUAL expr 364 { $$ = new AssignExprNode(IdentExprNode::Ptr($2), ExprNode::Ptr($4)); 365 parser.set_loc($$, @$); } 366 | TDOT ident bitop TEQUAL expr 367 { $$ = new AssignExprNode(IdentExprNode::Ptr($2), ExprNode::Ptr($5)); $$->bitop_ = BitopExprNode::Ptr($3); 368 parser.set_loc($$, @$); } 369 ; 370 371if_stmt 372 : TIF expr enter_varscope block exit_varscope 373 { $$ = new IfStmtNode(ExprNode::Ptr($2), StmtNode::Ptr($4)); 374 $4->scope_ = $3; 375 parser.set_loc($$, @$); } 376 | TIF expr enter_varscope block exit_varscope TELSE enter_varscope block exit_varscope 377 { $$ = new IfStmtNode(ExprNode::Ptr($2), StmtNode::Ptr($4), StmtNode::Ptr($8)); 378 $4->scope_ = $3; $8->scope_ = $7; 379 parser.set_loc($$, @$); } 380 | TIF expr enter_varscope block exit_varscope TELSE if_stmt 381 { $$ = new IfStmtNode(ExprNode::Ptr($2), StmtNode::Ptr($4), StmtNode::Ptr($7)); 382 $4->scope_ = $3; 383 parser.set_loc($$, @$); } 384 ; 385 386onvalid_stmt 387 : TVALID TLPAREN ident TRPAREN enter_varscope block exit_varscope 388 { $$ = new OnValidStmtNode(IdentExprNode::Ptr($3), StmtNode::Ptr($6)); 389 $6->scope_ = $5; 390 parser.set_loc($$, @$); } 391 | TVALID TLPAREN ident TRPAREN enter_varscope block exit_varscope TELSE enter_varscope block exit_varscope 392 { $$ = new OnValidStmtNode(IdentExprNode::Ptr($3), StmtNode::Ptr($6), StmtNode::Ptr($10)); 393 $6->scope_ = $5; $10->scope_ = $9; 394 parser.set_loc($$, @$); } 395 ; 396 397switch_stmt 398 : TSWITCH expr TLBRACE case_stmts TRBRACE 399 { $$ = new SwitchStmtNode(ExprNode::Ptr($2), make_unique<BlockStmtNode>(move(*$4))); delete $4; 400 parser.set_loc($$, @$); } 401 ; 402 403case_stmts 404 : case_stmt 405 { $$ = new StmtNodeList; $$->push_back(StmtNode::Ptr($1)); } 406 | case_stmts case_stmt 407 { $$->push_back(StmtNode::Ptr($2)); } 408 ; 409 410case_stmt 411 : TCASE numeric block TSEMI 412 { $$ = new CaseStmtNode(IntegerExprNode::Ptr($2), BlockStmtNode::Ptr($3)); 413 parser.set_loc($$, @$); } 414 | TCASE TMUL block TSEMI 415 { $$ = new CaseStmtNode(BlockStmtNode::Ptr($3)); 416 parser.set_loc($$, @$); } 417 ; 418 419numeric 420 : TINTEGER 421 { $$ = new IntegerExprNode($1); 422 parser.set_loc($$, @$); } 423 | THEXINTEGER 424 { $$ = new IntegerExprNode($1); 425 parser.set_loc($$, @$); } 426 | TINTEGER TCOLON TINTEGER 427 { $$ = new IntegerExprNode($1, $3); 428 parser.set_loc($$, @$); } 429 | THEXINTEGER TCOLON TINTEGER 430 { $$ = new IntegerExprNode($1, $3); 431 parser.set_loc($$, @$); } 432 | TTRUE 433 { $$ = new IntegerExprNode(new string("1"), new string("1")); 434 parser.set_loc($$, @$); } 435 | TFALSE 436 { $$ = new IntegerExprNode(new string("0"), new string("1")); 437 parser.set_loc($$, @$); } 438 ; 439 440assign_expr 441 : expr TEQUAL expr 442 { $$ = new AssignExprNode(ExprNode::Ptr($1), ExprNode::Ptr($3)); 443 parser.set_loc($$, @$); } 444 /* The below has a reduce/reduce conflict. 445 TODO: ensure the above is handled in the type check properly */ 446 /*| dotted_ident TEQUAL expr 447 { $$ = new AssignExprNode(IdentExprNode::Ptr($1), ExprNode::Ptr($3)); 448 parser.set_loc($$, @$); } 449 | dotted_ident bitop TEQUAL expr 450 { $$ = new AssignExprNode(IdentExprNode::Ptr($1), ExprNode::Ptr($4)); $$->bitop_ = BitopExprNode::Ptr($2); 451 parser.set_loc($$, @$); }*/ 452 ; 453 454return_expr 455 : TRETURN expr 456 { $$ = new ReturnExprNode(ExprNode::Ptr($2)); 457 parser.set_loc($$, @$); } 458 ; 459 460expr 461 : call_expr 462 { $$ = $1; } 463 | call_expr bitop 464 { $$ = $1; $$->bitop_ = BitopExprNode::Ptr($2); } 465 | table_index_expr 466 { $$ = $1; } 467 | table_index_expr TDOT ident 468 { $$ = $1; $1->sub_ = IdentExprNode::Ptr($3); } 469 | any_ident 470 { $$ = $1; } 471 | TAT dotted_ident 472 { $$ = new PacketExprNode(IdentExprNode::Ptr($2)); 473 $$->flags_[ExprNode::IS_REF] = true; 474 parser.set_loc($$, @$); } 475 | TDOLLAR dotted_ident 476 { $$ = new PacketExprNode(IdentExprNode::Ptr($2)); 477 $$->flags_[ExprNode::IS_PKT] = true; 478 parser.set_loc($$, @$); } 479 | TDOLLAR dotted_ident bitop 480 { $$ = new PacketExprNode(IdentExprNode::Ptr($2)); $$->bitop_ = BitopExprNode::Ptr($3); 481 $$->flags_[ExprNode::IS_PKT] = true; 482 parser.set_loc($$, @$); } 483 | TGOTO scoped_ident 484 { $$ = new GotoExprNode(IdentExprNode::Ptr($2), false); 485 parser.set_loc($$, @$); } 486 | TNEXT scoped_ident 487 { $$ = new GotoExprNode(IdentExprNode::Ptr($2), false); 488 parser.set_loc($$, @$); } 489 | TCONTINUE scoped_ident 490 { $$ = new GotoExprNode(IdentExprNode::Ptr($2), true); 491 parser.set_loc($$, @$); } 492 | TLPAREN expr TRPAREN 493 { $$ = $2; } 494 | TLPAREN expr TRPAREN bitop 495 { $$ = $2; $$->bitop_ = BitopExprNode::Ptr($4); } 496 | TSTRING 497 { $$ = new StringExprNode($1); 498 parser.set_loc($$, @$); } 499 | numeric 500 { $$ = $1; } 501 | numeric bitop 502 { $$ = $1; $$->bitop_ = BitopExprNode::Ptr($2); } 503 | expr TCLT expr 504 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 505 parser.set_loc($$, @$); } 506 | expr TCGT expr 507 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 508 parser.set_loc($$, @$); } 509 | expr TCGE expr 510 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 511 parser.set_loc($$, @$); } 512 | expr TCLE expr 513 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 514 parser.set_loc($$, @$); } 515 | expr TCNE expr 516 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 517 parser.set_loc($$, @$); } 518 | expr TCEQ expr 519 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 520 parser.set_loc($$, @$); } 521 | expr TPLUS expr 522 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 523 parser.set_loc($$, @$); } 524 | expr TMINUS expr 525 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 526 parser.set_loc($$, @$); } 527 | expr TMUL expr 528 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 529 parser.set_loc($$, @$); } 530 | expr TDIV expr 531 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 532 parser.set_loc($$, @$); } 533 | expr TMOD expr 534 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 535 parser.set_loc($$, @$); } 536 | expr TXOR expr 537 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 538 parser.set_loc($$, @$); } 539 | expr TAND expr 540 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 541 parser.set_loc($$, @$); } 542 | expr TOR expr 543 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 544 parser.set_loc($$, @$); } 545 | expr TLAND expr 546 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 547 parser.set_loc($$, @$); } 548 | expr TLOR expr 549 { $$ = new BinopExprNode(ExprNode::Ptr($1), $2, ExprNode::Ptr($3)); 550 parser.set_loc($$, @$); } 551 /*| expr bitop 552 { $$ = $1; $$->bitop_ = BitopExprNode::Ptr($2); }*/ 553 | TNOT expr 554 { $$ = new UnopExprNode($1, ExprNode::Ptr($2)); 555 parser.set_loc($$, @$); } 556 | TCMPL expr 557 { $$ = new UnopExprNode($1, ExprNode::Ptr($2)); 558 parser.set_loc($$, @$); } 559 ; 560 561call_args 562 : /* empty */ 563 { $$ = new ExprNodeList; } 564 | expr 565 { $$ = new ExprNodeList; $$->push_back(ExprNode::Ptr($1)); } 566 | call_args TCOMMA expr 567 { $$->push_back(ExprNode::Ptr($3)); } 568 ; 569 570bitop 571 : TLBRACK TCOLON TPLUS TINTEGER TRBRACK 572 { $$ = new BitopExprNode(string("0"), *$4); delete $4; 573 parser.set_loc($$, @$); } 574 | TLBRACK TINTEGER TCOLON TPLUS TINTEGER TRBRACK 575 { $$ = new BitopExprNode(*$2, *$5); delete $2; delete $5; 576 parser.set_loc($$, @$); } 577 ; 578 579table_index_expr 580 : dotted_ident TLBRACK ident TRBRACK 581 { $$ = new TableIndexExprNode(IdentExprNode::Ptr($1), IdentExprNode::Ptr($3)); 582 parser.set_loc($$, @$); } 583 ; 584 585scoped_ident 586 : ident 587 { $$ = $1; } 588 | scoped_ident TSCOPE TIDENTIFIER 589 { $$->append_scope(*$3); delete $3; } 590 ; 591 592dotted_ident 593 : ident 594 { $$ = $1; } 595 | dotted_ident TDOT TIDENTIFIER 596 { $$->append_dot(*$3); delete $3; } 597 ; 598 599any_ident 600 : ident 601 { $$ = $1; } 602 | dotted_ident TARROW TIDENTIFIER 603 { $$->append_dot(*$3); delete $3; } 604 | dotted_ident TDOT TIDENTIFIER 605 { $$->append_dot(*$3); delete $3; } 606 | scoped_ident TSCOPE TIDENTIFIER 607 { $$->append_scope(*$3); delete $3; } 608 ; 609 610ident 611 : TIDENTIFIER 612 { $$ = new IdentExprNode(*$1); delete $1; 613 parser.set_loc($$, @$); } 614 ; 615 616%% 617 618void ebpf::cc::BisonParser::error(const ebpf::cc::BisonParser::location_type &loc, 619 const string& msg) { 620 std::cerr << "Error: " << loc << " " << msg << std::endl; 621} 622 623#include "lexer.h" 624static int yylex(ebpf::cc::BisonParser::semantic_type *yylval, 625 ebpf::cc::BisonParser::location_type *yylloc, 626 ebpf::cc::Lexer &lexer) { 627 return lexer.yylex(yylval, yylloc); 628} 629 630