cint_grammar.y (25129B)
1 %{ 2 /* 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * File: cint_grammar.y 9 * Purpose: CINT C Parser 10 */ 11 %} 12 /* 13 * Parser Generator Options 14 */ 15 16 /* Pure, rentrant */ 17 %define api.pure 18 %define api.push_pull "both" 19 %name-prefix="cint_c_" 20 21 /* Include location information */ 22 %locations 23 24 /* The scanner object is the first argument to for the parser */ 25 %parse-param { yyscan_t yyscanner } 26 /* The cint_c_parser_t control structure is the second parameter to the parse function */ 27 %parse-param { cint_cparser_t* cparser } 28 29 /* The scanner object must be passed to yylex() */ 30 %lex-param { yyscan_t yyscanner } 31 32 /* 33 * TOKENS 34 */ 35 36 %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF 37 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP 38 %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN 39 %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN 40 %token XOR_ASSIGN OR_ASSIGN TYPE_NAME 41 42 %token TYPEDEF EXTERN STATIC AUTO REGISTER 43 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE T_VOID 44 %token STRUCT UNION ENUM ELLIPSIS 45 46 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 47 48 /* ADDED */ 49 %token PRINT CINT 50 51 /* Programmable Language Extensions */ 52 %token ITERATOR MACRO 53 54 %token XEOF 0 55 56 %{ 57 58 #ifndef LONGEST_SOURCE_LINE 59 #define LONGEST_SOURCE_LINE 256 60 #endif 61 62 typedef struct cint_c_parser_s { 63 int x; 64 } cint_c_parser_t; 65 66 typedef void* yyscan_t; 67 68 #define YY_TYPEDEF_YY_SCANNER_T 69 #define YYERROR_VERBOSE 1 70 71 #include "cint_config.h" 72 #include "cint_parser.h" 73 74 #include "cint_yy.h" 75 #include "cint_c.tab.h" 76 77 78 void cint_c_error(YYLTYPE * locp, yyscan_t yyscanner, cint_cparser_t * cp, 79 const char *msg); 80 extern int cint_c_lex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param, 81 yyscan_t yyscanner); 82 char *cint_current_line(yyscan_t yyscanner, char *const lineBuffer, const int lineLen, 83 int *column, int *tokLen, char **curFile, int *curLine); 84 85 86 #if CINT_CONFIG_INCLUDE_PARSER == 1 87 88 89 #include "cint_interpreter.h" 90 91 92 %} 93 94 95 96 %start translation_unit 97 98 %% 99 100 primary_expression 101 : IDENTIFIER { $$ = $1; } 102 | CONSTANT { $$ = $1; } 103 | STRING_LITERAL { $$ = $1; } 104 | '(' expression ')' { $$ = $2; } 105 ; 106 107 postfix_expression 108 : primary_expression { $$ = $1; } 109 | postfix_expression '[' expression ']' { $$ = cint_ast_operator(cintOpOpenBracket, $1, $3); } 110 | postfix_expression '(' ')' 111 { 112 $$ = cint_ast_function($1, 0); 113 } 114 | postfix_expression '(' argument_expression_list ')' 115 { 116 $$ = cint_ast_function($1, $3); 117 } 118 | postfix_expression '.' IDENTIFIER 119 { 120 $$ = cint_ast_operator(cintOpDot, $1, $3); 121 } 122 | postfix_expression PTR_OP IDENTIFIER 123 { 124 $$ = cint_ast_operator(cintOpArrow, $1, $3); 125 } 126 | postfix_expression INC_OP { $$ = cint_ast_operator(cintOpIncrement, $1, 0); } 127 | postfix_expression DEC_OP { $$ = cint_ast_operator(cintOpDecrement, $1, 0); } 128 ; 129 130 argument_expression_list 131 : assignment_expression 132 | argument_expression_list ',' assignment_expression 133 { 134 cint_ast_append($1, $3); 135 $$ = $1; 136 } 137 ; 138 139 unary_expression 140 : postfix_expression { $$ = $1; } 141 | INC_OP unary_expression { $$ = cint_ast_operator(cintOpIncrement, 0, $2); } 142 | DEC_OP unary_expression { $$ = cint_ast_operator(cintOpDecrement, 0, $2); } 143 | unary_operator cast_expression { $$ = cint_ast_operator(cint_ast_int($1), 0, $2); } 144 | SIZEOF unary_expression { $$ = cint_ast_operator(cintOpSizeof, 0, $2); } 145 | SIZEOF '(' type_name ')' { $$ = cint_ast_operator(cintOpSizeof, 0, $3); } 146 ; 147 148 unary_operator 149 : '&' { $$ = cint_ast_integer(cintOpAddressOf); } 150 | '*' { $$ = cint_ast_integer(cintOpDereference); } 151 | '+' { $$ = cint_ast_integer(cintOpPositive); } 152 | '-' { $$ = cint_ast_integer(cintOpNegative); } 153 | '~' { $$ = cint_ast_integer(cintOpTilde); } 154 | '!' { $$ = cint_ast_integer(cintOpNot); } 155 ; 156 157 cast_expression 158 : unary_expression 159 /* | '(' type_name ')' cast_expression { $$ = cint_ast_operator(cintOpTypecast, $2, $4); } */ 160 161 | '(' T_VOID '*' ')' cast_expression { $$ = cint_ast_operator(cintOpTypecast, CINT_AST_PTR_VOID, $5); } 162 163 | '(' AUTO ')' cast_expression { $$ = cint_ast_operator(cintOpTypecast, CINT_AST_PTR_AUTO, $4); } 164 ; 165 166 multiplicative_expression 167 : cast_expression 168 | multiplicative_expression '*' cast_expression { $$ = cint_ast_operator(cintOpMultiply, $1, $3); } 169 | multiplicative_expression '/' cast_expression { $$ = cint_ast_operator(cintOpDivide, $1, $3); } 170 | multiplicative_expression '%' cast_expression { $$ = cint_ast_operator(cintOpMod, $1, $3); } 171 ; 172 173 additive_expression 174 : multiplicative_expression 175 | additive_expression '+' multiplicative_expression { $$ = cint_ast_operator(cintOpAdd, $1, $3); } 176 | additive_expression '-' multiplicative_expression { $$ = cint_ast_operator(cintOpSubtract, $1, $3); } 177 ; 178 179 shift_expression 180 : additive_expression 181 | shift_expression LEFT_OP additive_expression { $$ = cint_ast_operator(cintOpLeftShift, $1, $3); } 182 | shift_expression RIGHT_OP additive_expression { $$ = cint_ast_operator(cintOpRightShift, $1, $3); } 183 ; 184 185 relational_expression 186 : shift_expression 187 | relational_expression '<' shift_expression { $$ = cint_ast_operator(cintOpLessThan, $1, $3); } 188 | relational_expression '>' shift_expression { $$ = cint_ast_operator(cintOpGreaterThan, $1, $3); } 189 | relational_expression LE_OP shift_expression { $$ = cint_ast_operator(cintOpLessThanOrEqual, $1, $3); } 190 | relational_expression GE_OP shift_expression { $$ = cint_ast_operator(cintOpGreaterThanOrEqual, $1, $3); } 191 ; 192 193 equality_expression 194 : relational_expression 195 | equality_expression EQ_OP relational_expression { $$ = cint_ast_operator(cintOpEqual, $1, $3); } 196 | equality_expression NE_OP relational_expression { $$ = cint_ast_operator(cintOpNotEqual, $1, $3); } 197 ; 198 199 and_expression 200 : equality_expression 201 | and_expression '&' equality_expression { $$ = cint_ast_operator(cintOpBitwiseAnd, $1, $3); } 202 ; 203 204 exclusive_or_expression 205 : and_expression 206 | exclusive_or_expression '^' and_expression { $$ = cint_ast_operator(cintOpBitwiseXor, $1, $3); } 207 ; 208 209 inclusive_or_expression 210 : exclusive_or_expression 211 | inclusive_or_expression '|' exclusive_or_expression { $$ = cint_ast_operator(cintOpBitwiseOr, $1, $3); } 212 ; 213 214 logical_and_expression 215 : inclusive_or_expression 216 | logical_and_expression AND_OP inclusive_or_expression { $$ = cint_ast_operator(cintOpLogicalAnd, $1, $3); } 217 ; 218 219 logical_or_expression 220 : logical_and_expression 221 | logical_or_expression OR_OP logical_and_expression { $$ = cint_ast_operator(cintOpLogicalOr, $1, $3); } 222 ; 223 224 conditional_expression 225 : logical_or_expression 226 | logical_or_expression '?' expression ':' conditional_expression 227 { $$ = cint_ast_ternary($1, $3, $5); } 228 ; 229 230 assignment_expression 231 : conditional_expression 232 | unary_expression assignment_operator assignment_expression 233 { 234 /* 235 * Arithmetic assignment operators are converted to distinct operator/= expressions 236 * for the benefit of simplifying the interpreter operator logic. 237 * 238 * Convert any expressions of the form "x <op>= y" to "x = x <op> y"; 239 */ 240 $$ = cint_ast_operator(cint_ast_int($2), $1, $3); 241 if(cint_ast_int($2) != cintOpAssign) { 242 /* Perform the operator on the left and right and assign it to the left */ 243 $$ = cint_ast_operator(cintOpAssign, $1, $$); 244 } 245 } 246 ; 247 248 assignment_operator 249 : '=' { $$ = cint_ast_integer(cintOpAssign); } 250 | MUL_ASSIGN { $$ = cint_ast_integer(cintOpMultiply); } 251 | DIV_ASSIGN { $$ = cint_ast_integer(cintOpDivide); } 252 | MOD_ASSIGN { $$ = cint_ast_integer(cintOpMod); } 253 | ADD_ASSIGN { $$ = cint_ast_integer(cintOpAdd); } 254 | SUB_ASSIGN { $$ = cint_ast_integer(cintOpSubtract); } 255 | LEFT_ASSIGN { $$ = cint_ast_integer(cintOpLeftShift); } 256 | RIGHT_ASSIGN { $$ = cint_ast_integer(cintOpRightShift); } 257 | AND_ASSIGN { $$ = cint_ast_integer(cintOpBitwiseAnd); } 258 | XOR_ASSIGN { $$ = cint_ast_integer(cintOpBitwiseXor); } 259 | OR_ASSIGN { $$ = cint_ast_integer(cintOpBitwiseOr); } 260 ; 261 262 expression 263 : assignment_expression { $$ = $1; } 264 | expression ',' assignment_expression 265 { 266 $$ = cint_ast_comma($1, $3); 267 } 268 ; 269 270 constant_expression 271 : conditional_expression 272 ; 273 274 declaration 275 : declaration_specifiers ';' { $$ = $1; } 276 | declaration_specifiers init_declarator_list ';' 277 { 278 $$ = cint_ast_declaration_init($1, $2); 279 } 280 ; 281 282 declaration_specifiers 283 : storage_class_specifier {$$ = $1; } 284 | storage_class_specifier declaration_specifiers { cint_ast_append($1, $2); $$ = $1; } 285 | type_specifier { $$ = $1; } 286 | type_specifier declaration_specifiers { cint_ast_append($1, $2); $$ = $1; } 287 | type_qualifier 288 | type_qualifier declaration_specifiers { cint_ast_append($1, $2); $$ = $1; } 289 ; 290 291 init_declarator_list 292 : init_declarator 293 | init_declarator_list ',' init_declarator { cint_ast_append($1, $3); $$ = $1; } 294 ; 295 296 init_declarator 297 : declarator { $$ = $1; } 298 | declarator '=' initializer 299 { $$ = cint_ast_declarator_init($1, $3); } 300 ; 301 302 storage_class_specifier 303 : EXTERN { $$ = cint_ast_integer(CINT_AST_TYPE_F_EXTERN); } 304 | TYPEDEF { $$ = cint_ast_integer(CINT_AST_TYPE_F_TYPEDEF); } 305 | STATIC { $$ = cint_ast_integer(CINT_AST_TYPE_F_STATIC); } 306 | AUTO /* IGNORED */ 307 | REGISTER /* IGNORED */ 308 ; 309 310 type_specifier 311 : T_VOID { $$ = cint_ast_type("void"); } 312 | CHAR { $$ = cint_ast_type("char"); } 313 | SHORT { $$ = cint_ast_type("short"); } 314 | INT { $$ = cint_ast_type("int"); } 315 | LONG { $$ = cint_ast_type("long"); } 316 | FLOAT { $$ = cint_ast_type("float"); } 317 | DOUBLE { $$ = cint_ast_type("double"); } 318 | SIGNED { $$ = cint_ast_integer(CINT_AST_TYPE_F_SIGNED); } 319 | UNSIGNED { $$ = cint_ast_integer(CINT_AST_TYPE_F_UNSIGNED); } 320 | struct_or_union_specifier 321 | enum_specifier 322 | TYPE_NAME { $$ = $1; } 323 ; 324 325 struct_or_union_specifier 326 : struct_or_union IDENTIFIER '{' struct_declaration_list '}' { $$ = cint_ast_structure_def($2, $4); } 327 | struct_or_union '{' struct_declaration_list '}' { $$ = cint_ast_structure_def(0, $3); } 328 | struct_or_union IDENTIFIER 329 ; 330 331 struct_or_union 332 : STRUCT 333 | UNION 334 ; 335 336 struct_declaration_list 337 : struct_declaration 338 | struct_declaration_list struct_declaration { cint_ast_append($1, $2); $$ = $1; } 339 ; 340 341 struct_declaration 342 : specifier_qualifier_list struct_declarator_list ';' 343 { 344 $$ = cint_ast_struct_declaration($1, $2); 345 } 346 347 ; 348 349 struct_declarator_list 350 : struct_declarator 351 | struct_declarator_list ',' struct_declarator { cint_ast_append($1, $3); $$ = $1; } 352 ; 353 354 struct_declarator 355 : declarator 356 /* | ':' constant_expression NOT SUPPORTED */ 357 /* | declarator ':' constant_expression NOT SUPPORTED */ 358 ; 359 360 enum_specifier 361 : ENUM '{' enumerator_list '}' 362 | ENUM IDENTIFIER '{' enumerator_list '}' { $$ = cint_ast_enumdef($2, $4); } 363 | ENUM IDENTIFIER 364 ; 365 366 enumerator_list 367 : enumerator { $$ = $1; } 368 | enumerator_list ',' enumerator { cint_ast_append($1, $3); $$ = $1; } 369 ; 370 371 enumerator 372 : IDENTIFIER { $$ = cint_ast_enumerator($1, 0); } 373 | IDENTIFIER '=' constant_expression { $$ = cint_ast_enumerator($1, $3); } 374 ; 375 376 specifier_qualifier_list 377 : type_specifier specifier_qualifier_list { cint_ast_append($1, $2); $$ = $1; } 378 | type_specifier { $$ = $1; } 379 | type_qualifier specifier_qualifier_list { cint_ast_append($1, $2); $$ = $1; } 380 | type_qualifier { $$ = $1; } 381 ; 382 383 type_qualifier 384 : CONST { $$ = cint_ast_integer(CINT_AST_TYPE_F_CONST); } 385 | VOLATILE { $$ = cint_ast_integer(CINT_AST_TYPE_F_VOLATILE); } 386 ; 387 388 declarator 389 : pointer direct_declarator 390 { 391 $$ = cint_ast_pointer_declarator($1, $2); 392 } 393 | direct_declarator { $$ = $1; } 394 ; 395 396 direct_declarator 397 : IDENTIFIER { $$ = cint_ast_identifier_declarator($1); } 398 | '(' declarator ')' 399 | direct_declarator '[' constant_expression ']' 400 { $$ = cint_ast_array_declarator($1, $3); } 401 | direct_declarator '[' ']' 402 { $$ = cint_ast_array_declarator($1, cint_ast_integer(-1)); } 403 | direct_declarator '(' parameter_type_list ')' 404 { 405 $$ = cint_ast_function_declarator($1, $3); 406 } 407 /* | direct_declarator '(' identifier_list ')' K&R NOT SUPPORTED */ 408 | direct_declarator '(' ')' 409 { 410 $$ = cint_ast_function_declarator($1, 0); 411 } 412 ; 413 414 pointer 415 : '*' { $$ = cint_ast_integer(1); } 416 | '*' type_qualifier_list { $$ = cint_ast_integer(1); } /* QUALIFIER NOT SUPPORTED */ 417 | '*' pointer { $$ = cint_ast_pointer_indirect($2); } 418 | '*' type_qualifier_list pointer /* NOT SUPPORTED */ 419 ; 420 421 type_qualifier_list 422 : type_qualifier 423 | type_qualifier_list type_qualifier { cint_ast_append($1, $2); $$ = $1; } 424 ; 425 426 427 parameter_type_list 428 : parameter_list 429 /* | parameter_list ',' ELLIPSIS REMOVED */ 430 ; 431 432 parameter_list 433 : parameter_declaration {$$ = $1;} 434 | parameter_list ',' parameter_declaration 435 { 436 cint_ast_append($1, $3); 437 $$ = $1; 438 } 439 ; 440 441 parameter_declaration 442 : declaration_specifiers declarator 443 { 444 $$ = cint_ast_parameter_declaration_append($1, $2); 445 } 446 | declaration_specifiers abstract_declarator 447 | declaration_specifiers 448 { 449 $$ = cint_ast_parameter_declaration($1); 450 } 451 ; 452 453 /* 454 * K&R not supported 455 identifier_list 456 : IDENTIFIER 457 | identifier_list ',' IDENTIFIER 458 ; 459 */ 460 461 type_name 462 : specifier_qualifier_list 463 | specifier_qualifier_list abstract_declarator 464 ; 465 466 abstract_declarator 467 : pointer 468 | direct_abstract_declarator 469 | pointer direct_abstract_declarator 470 ; 471 472 direct_abstract_declarator 473 : '(' abstract_declarator ')' 474 | '[' ']' 475 | '[' constant_expression ']' 476 | direct_abstract_declarator '[' ']' 477 | direct_abstract_declarator '[' constant_expression ']' 478 | '(' ')' 479 | '(' parameter_type_list ')' 480 | direct_abstract_declarator '(' ')' 481 | direct_abstract_declarator '(' parameter_type_list ')' 482 ; 483 484 initializer 485 : assignment_expression { $$ = $1; } 486 | '{' initializer_list '}' { $$ = cint_ast_initializer($2); } 487 | '{' initializer_list ',' '}' { $$ = cint_ast_initializer($2); } 488 ; 489 490 initializer_list 491 : initializer 492 | initializer_list ',' initializer { cint_ast_append($1, $3); $$ = $1; } 493 ; 494 495 statement 496 : labeled_statement /* NOT SUPPORTED */ 497 | declaration_statement /* ADDED -- declarations are now statements */ 498 | compound_statement 499 { 500 $$ = cint_ast_compound_statement($1); 501 } 502 503 | expression_statement 504 | selection_statement 505 | iteration_statement {$$=$1;} 506 | jump_statement 507 | print_statement /* ADDED */ 508 | cint_statement /* ADDED */ 509 | IDENTIFIER ';' { $$ = cint_ast_statement_with_no_effect($1); } 510 | CONSTANT ';' { $$ = cint_ast_statement_with_no_effect($1); } 511 | STRING_LITERAL ';' { $$ = cint_ast_statement_with_no_effect($1); } 512 ; 513 514 515 print_statement 516 : PRINT expression_statement { $$ = cint_ast_print($2); } 517 | PRINT TYPE_NAME ';' { $$ = cint_ast_print($2); } 518 519 520 keyword_arg 521 : SIZEOF { $$ = cint_ast_string("sizeof"); } 522 | TYPEDEF { $$ = cint_ast_string("typedef"); } 523 | EXTERN { $$ = cint_ast_string("extern"); } 524 | STATIC { $$ = cint_ast_string("static"); } 525 | AUTO { $$ = cint_ast_string("auto"); } 526 | REGISTER { $$ = cint_ast_string("register"); } 527 | CHAR { $$ = cint_ast_string("char"); } 528 | SHORT { $$ = cint_ast_string("short"); } 529 | INT { $$ = cint_ast_string("int"); } 530 | LONG { $$ = cint_ast_string("long"); } 531 | SIGNED { $$ = cint_ast_string("signed"); } 532 | UNSIGNED { $$ = cint_ast_string("unsigned"); } 533 | FLOAT { $$ = cint_ast_string("float"); } 534 | DOUBLE { $$ = cint_ast_string("double"); } 535 | CONST { $$ = cint_ast_string("const"); } 536 | VOLATILE { $$ = cint_ast_string("volatile"); } 537 | T_VOID { $$ = cint_ast_string("void"); } 538 | STRUCT { $$ = cint_ast_string("struct"); } 539 | UNION { $$ = cint_ast_string("union"); } 540 | ENUM { $$ = cint_ast_string("enum"); } 541 | CASE { $$ = cint_ast_string("case"); } 542 | DEFAULT { $$ = cint_ast_string("default"); } 543 | IF { $$ = cint_ast_string("if"); } 544 | ELSE { $$ = cint_ast_string("else"); } 545 | SWITCH { $$ = cint_ast_string("switch"); } 546 | WHILE { $$ = cint_ast_string("while"); } 547 | DO { $$ = cint_ast_string("do"); } 548 | FOR { $$ = cint_ast_string("for"); } 549 | GOTO { $$ = cint_ast_string("goto"); } 550 | CONTINUE { $$ = cint_ast_string("continue"); } 551 | BREAK { $$ = cint_ast_string("break"); } 552 | RETURN { $$ = cint_ast_string("return"); } 553 | CINT { $$ = cint_ast_string("cint"); } 554 | PRINT { $$ = cint_ast_string("print"); } 555 556 557 558 559 cint_argument 560 : IDENTIFIER 561 | TYPE_NAME 562 | STRING_LITERAL 563 | CONSTANT 564 | keyword_arg 565 566 567 cint_argument_list 568 : cint_argument 569 | cint_argument_list cint_argument 570 { 571 cint_ast_append($1, $2); 572 $$ = $1; 573 } 574 575 576 cint_statement 577 : CINT cint_argument_list ';' { $$ = cint_ast_cint($2); } 578 579 labeled_statement 580 : IDENTIFIER ':' statement 581 | CASE constant_expression ':' statement { $$ = cint_ast_case($2, $4); } 582 | DEFAULT ':' statement { $$ = cint_ast_case(0, $3); } 583 ; 584 585 declaration_statement 586 : declaration 587 588 compound_statement 589 : '{' '}' { $$ = cint_ast_empty(); } 590 | '{' statement_list '}' { $$ = $2; } 591 /* | '{' declaration_list '}' REMOVED -- declarations are now statements */ 592 /* | '{' declaration_list statement_list '}' REMOVED -- declarations are now statements */ 593 ; 594 595 declaration_list 596 : declaration { $$ = $1; } 597 | declaration_list declaration { $$ = $1; cint_ast_append($1, $2); } 598 ; 599 600 statement_list 601 : statement { $$ = $1; } 602 | statement_list statement 603 { 604 cint_ast_append($1, $2); 605 $$ = $1; 606 } 607 ; 608 609 expression_statement 610 : ';' { $$ = cint_ast_empty(); } 611 | expression ';' 612 ; 613 614 selection_statement 615 : IF '(' expression ')' statement 616 { 617 $$ = cint_ast_if($3, $5, 0); 618 } 619 | IF '(' expression ')' statement ELSE statement 620 { 621 $$ = cint_ast_if($3, $5, $7); 622 } 623 | SWITCH '(' expression ')' statement { $$ = cint_ast_switch($3, $5); } 624 | MACRO '(' argument_expression_list ')' ';' { $$ = cint_interpreter_macro($1, $3); } 625 ; 626 627 iteration_statement 628 : WHILE '(' expression ')' statement 629 { 630 $$ = cint_ast_while($3, $5, 0); 631 } 632 | DO statement WHILE '(' expression ')' ';' 633 { 634 $$ = cint_ast_while($5, $2, 1); 635 } 636 | FOR '(' expression_statement expression_statement ')' statement 637 { 638 $$ = cint_ast_for($3, $4, 0, $6); 639 } 640 | FOR '(' expression_statement expression_statement expression ')' statement 641 { 642 $$ = cint_ast_for($3, $4, $5, $7); 643 } 644 | ITERATOR '(' argument_expression_list ')' statement 645 { 646 $$ = cint_interpreter_iterator($1, $3, $5); 647 } 648 | ITERATOR '(' ')' statement 649 { 650 $$ = cint_interpreter_iterator($1, 0, $3); 651 } 652 ; 653 654 jump_statement 655 : GOTO IDENTIFIER ';' /* NOT SUPPORTED */ 656 | CONTINUE ';' { $$ = cint_ast_continue(); } 657 | BREAK ';' { $$ = cint_ast_break(); } 658 | RETURN ';' { $$ = cint_ast_return(0); } 659 | RETURN expression ';' { $$ = cint_ast_return($2); } 660 ; 661 662 663 translation_unit 664 : external_declaration 665 { 666 /* Accept and append this translation unit */ 667 if(cparser->result) { 668 cint_ast_append(cparser->result, $1); 669 } 670 else { 671 cparser->result = $1; 672 } 673 674 if(yychar == YYEMPTY) { 675 /* 676 * This unit is complete and we have no dangling lookahead. 677 * Return to the application. 678 */ 679 YYACCEPT; 680 } 681 else { 682 /* 683 * A lookahead has been consumed. If we were to return from parsing 684 * now we would lose the lookahead on the next invokation. 685 * 686 * We will continue to parse units until it is safe to return. 687 */ 688 } 689 } 690 | translation_unit external_declaration 691 { 692 /* Accept and append this translation unit */ 693 if(cparser->result) { 694 cint_ast_append(cparser->result, $2); 695 } 696 else { 697 cparser->result = $1; 698 } 699 700 if(yychar == YYEMPTY) { 701 /* 702 * This unit is complete and we have no dangling lookahead. 703 * Return to the application. 704 */ 705 YYACCEPT; 706 } 707 else { 708 /* 709 * A lookahead has been consumed. If we were to return from parsing 710 * now we would lose the lookahead on the next invokation. 711 * 712 * We will continue to parse units until it is safe to return. 713 */ 714 } 715 } 716 | XEOF /* Allow Empty Files/Translation Units */ 717 { 718 cparser->result = 0; 719 YYACCEPT; 720 } 721 ; 722 723 724 external_declaration 725 : function_definition 726 /* | declaration REMOVED -- Statements are also declarations */ 727 | statement; /* ADDED -- allow statements to be interpreted at top level */ 728 ; 729 730 function_definition 731 : declaration_specifiers declarator declaration_list compound_statement /* K&R NOT SUPPORTED */ 732 | declaration_specifiers declarator compound_statement 733 { 734 $$ = cint_ast_function_definition($1, $2, $3); 735 } 736 /* | declarator declaration_list compound_statement REMOVED */ 737 /* | declarator compound_statement REMOVED */ 738 ; 739 740 %% 741 742 #include "cint_porting.h" 743 744 void cint_c_error(YYLTYPE* locp, yyscan_t yyscanner, cint_cparser_t* cp, const char* msg) 745 { 746 const int sourceLineLen = LONGEST_SOURCE_LINE; /* Truncate source lines longer than 256 characters. */ 747 char sourceLine[LONGEST_SOURCE_LINE]; 748 char errLine[LONGEST_SOURCE_LINE]; 749 char *errPtr = errLine; 750 int errCol; 751 int tokLen; 752 int i; 753 char *currentFileName; 754 int currentLineNum; 755 756 (void) cint_current_line(yyscanner, sourceLine, sourceLineLen, &errCol, 757 &tokLen, ¤tFileName, ¤tLineNum); 758 if (sourceLine[0] && !cint_cparser_interactive()) { 759 /* Print current source line (if there is one) and not interactive */ 760 CINT_PRINTF("%s\n", sourceLine); 761 } 762 if (tokLen) { 763 /* Create a "marker" line pointing to offending token. */ 764 for (i = 0; i < errCol; i++) { 765 *errPtr++ = ' '; 766 } 767 for (i = 0; i < tokLen; i++) { 768 *errPtr++ = '^'; 769 } 770 *errPtr = 0; 771 errPtr = errLine; 772 } else { 773 /* If tokLen is zero, either the line was longer than max allowed or current line is empty. */ 774 errPtr = "[No current line]"; 775 } 776 777 /* print marker and parser message */ 778 if (currentFileName) { 779 /* If file name is NULL, we're at the top */ 780 CINT_PRINTF("%s %s [%s:%d]\n", errPtr, msg, currentFileName, currentLineNum); 781 } else if (currentLineNum) { 782 CINT_PRINTF("%s %s [%d]\n", errPtr, msg, currentLineNum); 783 } else { 784 CINT_PRINTF("%s %s\n", errPtr, msg); 785 } 786 } 787 788 789 #else /* CINT_CONFIG_INCLUDE_PARSER */ 790 int cint_grammar_c_not_empty; 791 #endif