openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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, &currentFileName, &currentLineNum);
    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