parser rewrite according to ANSI C grammar

same problem as before - conflict in IDENTIFIER as a type name versus an actual identifier
This commit is contained in:
Josh Holtrop 2018-05-07 23:48:08 -04:00
parent a7d63e51e5
commit 895ea27016
2 changed files with 587 additions and 504 deletions

View File

@ -31,111 +31,111 @@ void handle_loc(const char * input);
%% %%
\+ return TOK_PLUS; \+ return PLUS;
- return TOK_MINUS; - return MINUS;
\* return TOK_TIMES; \* return TIMES;
\/ return TOK_DIVIDE; \/ return DIVIDE;
% return TOK_MOD; % return MOD;
\^ return TOK_XOR; \^ return XOR;
= return TOK_ASSIGN; = return ASSIGN;
== return TOK_EQUALS; == return EQUALS;
!= return TOK_NOTEQUALS; != return NOTEQUALS;
\< return TOK_LESS; \< return LESS;
\<= return TOK_LESSEQ; \<= return LESSEQ;
\> return TOK_GREATER; \> return GREATER;
\>= return TOK_GREATEREQ; \>= return GREATEREQ;
&& return TOK_AND; && return AND;
\|\| return TOK_OR; \|\| return OR;
! return TOK_NOT; ! return NOT;
& return TOK_BITAND; & return BITAND;
\| return TOK_BITOR; \| return BITOR;
~ return TOK_BITNOT; ~ return BITNOT;
\+\+ return TOK_INCREMENT; \+\+ return INCREMENT;
-- return TOK_DECREMENT; -- return DECREMENT;
\<\< return TOK_LSHIFT; \<\< return LSHIFT;
\>\> return TOK_RSHIFT; \>\> return RSHIFT;
\+= return TOK_PLUSEQUALS; \+= return ADD_ASSIGN;
-= return TOK_MINUSEQUALS; -= return SUB_ASSIGN;
\*= return TOK_TIMESEQUALS; \*= return MUL_ASSIGN;
\/= return TOK_DIVIDEEQUALS; \/= return DIV_ASSIGN;
%= return TOK_MODEQUALS; %= return MOD_ASSIGN;
\^= return TOK_XOREQUALS; \^= return XOR_ASSIGN;
\<\<= return TOK_LSHIFTEQUALS; \<\<= return LEFT_ASSIGN;
\>\>= return TOK_RSHIFTEQUALS; \>\>= return RIGHT_ASSIGN;
&= return TOK_BITANDEQUALS; &= return AND_ASSIGN;
\|= return TOK_BITOREQUALS; \|= return OR_ASSIGN;
; return TOK_SEMICOLON; ; return SEMICOLON;
: return TOK_COLON; : return COLON;
\? return TOK_QUESTION; \? return QUESTION;
\. return TOK_DOT; \. return DOT;
-\> return TOK_ARROW; -\> return ARROW;
, return TOK_COMMA; , return COMMA;
\.\.\. return TOK_ELLIPSES; \.\.\. return ELLIPSIS;
\{ return TOK_LCURLY; \{ return LCURLY;
\} return TOK_RCURLY; \} return RCURLY;
\[ return TOK_LBRACKET; \[ return LBRACKET;
\] return TOK_RBRACKET; \] return RBRACKET;
\( return TOK_LPAREN; \( return LPAREN;
\) return TOK_RPAREN; \) return RPAREN;
void return TOK_VOID; void return VOID;
char return TOK_CHAR; char return CHAR;
short return TOK_SHORT; short return SHORT;
int return TOK_INT; int return INT;
long return TOK_LONG; long return LONG;
float return TOK_FLOAT; float return FLOAT;
double return TOK_DOUBLE; double return DOUBLE;
signed return TOK_SIGNED; signed return SIGNED;
unsigned return TOK_UNSIGNED; unsigned return UNSIGNED;
volatile return TOK_VOLATILE; volatile return VOLATILE;
static return TOK_STATIC; static return STATIC;
const return TOK_CONST; const return CONST;
extern return TOK_EXTERN; extern return EXTERN;
auto return TOK_AUTO; auto return AUTO;
register return TOK_REGISTER; register return REGISTER;
inline return TOK_INLINE; inline return INLINE;
struct return TOK_STRUCT; struct return STRUCT;
union return TOK_UNION; union return UNION;
enum return TOK_ENUM; enum return ENUM;
typedef return TOK_TYPEDEF; typedef return TYPEDEF;
if return TOK_IF; if return IF;
else return TOK_ELSE; else return ELSE;
while return TOK_WHILE; while return WHILE;
for return TOK_FOR; for return FOR;
do return TOK_DO; do return DO;
goto return TOK_GOTO; goto return GOTO;
return return TOK_RETURN; return return RETURN;
switch return TOK_SWITCH; switch return SWITCH;
case return TOK_CASE; case return CASE;
default return TOK_DEFAULT; default return DEFAULT;
break return TOK_BREAK; break return BREAK;
continue return TOK_CONTINUE; continue return CONTINUE;
sizeof return TOK_SIZEOF; sizeof return SIZEOF;
L?'[^\\]' return TOK_CHAR_CONST; L?'[^\\]' return CHAR_CONST;
L?'\\.' return TOK_CHAR_CONST; L?'\\.' return CHAR_CONST;
L?'\\a' (void)'\a'; return TOK_CHAR_CONST; L?'\\a' (void)'\a'; return CHAR_CONST;
L?'\\b' (void)'\b'; return TOK_CHAR_CONST; L?'\\b' (void)'\b'; return CHAR_CONST;
L?'\\f' (void)'\f'; return TOK_CHAR_CONST; L?'\\f' (void)'\f'; return CHAR_CONST;
L?'\\n' (void)'\n'; return TOK_CHAR_CONST; L?'\\n' (void)'\n'; return CHAR_CONST;
L?'\\r' (void)'\r'; return TOK_CHAR_CONST; L?'\\r' (void)'\r'; return CHAR_CONST;
L?'\\t' (void)'\t'; return TOK_CHAR_CONST; L?'\\t' (void)'\t'; return CHAR_CONST;
L?'\\v' (void)'\v'; return TOK_CHAR_CONST; L?'\\v' (void)'\v'; return CHAR_CONST;
L?'\\x[0-9A-Fa-f]{2}' return TOK_CHAR_CONST; L?'\\x[0-9A-Fa-f]{2}' return CHAR_CONST;
L?'\\[0-7]{1,3}' return TOK_CHAR_CONST; L?'\\[0-7]{1,3}' return CHAR_CONST;
[0-9]+([uU][lL]?[lL]?)? return TOK_INT_CONST; [0-9]+([uU][lL]?[lL]?)? return INT_CONST;
0[xX][0-9a-fA-F]+([uU][lL]?[lL]?)? return TOK_INT_CONST; 0[xX][0-9a-fA-F]+([uU][lL]?[lL]?)? return INT_CONST;
([0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?[fFlL]? return TOK_FLOAT_CONST; ([0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?[fFlL]? return FLOAT_CONST;
L?\" { L?\" {
if (build_string != NULL) if (build_string != NULL)
@ -148,7 +148,7 @@ L?\" {
<str>{ <str>{
\" { \" {
BEGIN(INITIAL); BEGIN(INITIAL);
return TOK_STR_CONST; return STRING_LITERAL;
} }
\\x[0-9A-Fa-f]{2} { \\x[0-9A-Fa-f]{2} {
/* hexadecimal escape code */ /* hexadecimal escape code */
@ -175,7 +175,7 @@ L?\" {
[^\\\"]+ String_concat(build_string, yytext); [^\\\"]+ String_concat(build_string, yytext);
} }
[a-zA-Z_][a-zA-Z_0-9]* return TOK_IDENTIFIER; [a-zA-Z_][a-zA-Z_0-9]* return IDENTIFIER;
^[ ]*#[ ]+[0-9]+[ ]+\".+\".*$ { ^[ ]*#[ ]+[0-9]+[ ]+\".+\".*$ {
handle_loc(yytext); handle_loc(yytext);

View File

@ -13,429 +13,512 @@ int yylex(YYSTYPE *, YYLTYPE *);
%locations %locations
%error-verbose %error-verbose
%token TOK_PLUS; %token PLUS;
%token TOK_MINUS; %token MINUS;
%token TOK_TIMES; %token TIMES;
%token TOK_DIVIDE; %token DIVIDE;
%token TOK_MOD; %token MOD;
%token TOK_XOR; %token XOR;
%token TOK_ASSIGN; %token ASSIGN;
%token TOK_EQUALS; %token EQUALS;
%token TOK_NOTEQUALS; %token NOTEQUALS;
%token TOK_LESS; %token LESS;
%token TOK_LESSEQ; %token LESSEQ;
%token TOK_GREATER; %token GREATER;
%token TOK_GREATEREQ; %token GREATEREQ;
%token TOK_AND; %token AND;
%token TOK_OR; %token OR;
%token TOK_NOT; %token NOT;
%token TOK_BITAND; %token BITAND;
%token TOK_BITOR; %token BITOR;
%token TOK_BITNOT; %token BITNOT;
%token TOK_INCREMENT %token INCREMENT
%token TOK_DECREMENT %token DECREMENT
%token TOK_LSHIFT %token LSHIFT
%token TOK_RSHIFT %token RSHIFT
%token TOK_PLUSEQUALS; %token ADD_ASSIGN;
%token TOK_MINUSEQUALS; %token SUB_ASSIGN;
%token TOK_TIMESEQUALS; %token MUL_ASSIGN;
%token TOK_DIVIDEEQUALS; %token DIV_ASSIGN;
%token TOK_MODEQUALS; %token MOD_ASSIGN;
%token TOK_XOREQUALS; %token XOR_ASSIGN;
%token TOK_LSHIFTEQUALS; %token LEFT_ASSIGN;
%token TOK_RSHIFTEQUALS; %token RIGHT_ASSIGN;
%token TOK_BITANDEQUALS; %token AND_ASSIGN;
%token TOK_BITOREQUALS; %token OR_ASSIGN;
%token TOK_SEMICOLON; %token SEMICOLON;
%token TOK_COLON; %token COLON;
%token TOK_QUESTION; %token QUESTION;
%token TOK_DOT; %token DOT;
%token TOK_ARROW; %token ARROW;
%token TOK_COMMA; %token COMMA;
%token TOK_ELLIPSES; %token ELLIPSIS;
%token TOK_LCURLY; %token LCURLY;
%token TOK_RCURLY; %token RCURLY;
%token TOK_LBRACKET; %token LBRACKET;
%token TOK_RBRACKET; %token RBRACKET;
%token TOK_LPAREN; %token LPAREN;
%token TOK_RPAREN; %token RPAREN;
%token TOK_VOID; %token VOID;
%token TOK_CHAR; %token CHAR;
%token TOK_SHORT; %token SHORT;
%token TOK_INT; %token INT;
%token TOK_LONG; %token LONG;
%token TOK_FLOAT; %token FLOAT;
%token TOK_DOUBLE; %token DOUBLE;
%token TOK_SIGNED; %token SIGNED;
%token TOK_UNSIGNED; %token UNSIGNED;
%token TOK_VOLATILE; %token VOLATILE;
%token TOK_STATIC; %token STATIC;
%token TOK_CONST; %token CONST;
%token TOK_EXTERN; %token EXTERN;
%token TOK_AUTO; %token AUTO;
%token TOK_REGISTER; %token REGISTER;
%token TOK_INLINE; %token INLINE;
%token TOK_STRUCT; %token STRUCT;
%token TOK_UNION; %token UNION;
%token TOK_ENUM; %token ENUM;
%token TOK_TYPEDEF; %token TYPEDEF;
%token TOK_IF; %token IF;
%token TOK_ELSE; %token ELSE;
%token TOK_WHILE; %token WHILE;
%token TOK_FOR; %token FOR;
%token TOK_DO; %token DO;
%token TOK_GOTO; %token GOTO;
%token TOK_RETURN; %token RETURN;
%token TOK_SWITCH; %token SWITCH;
%token TOK_CASE; %token CASE;
%token TOK_DEFAULT; %token DEFAULT;
%token TOK_BREAK; %token BREAK;
%token TOK_CONTINUE; %token CONTINUE;
%token TOK_SIZEOF; %token SIZEOF;
%token TOK_CHAR_CONST; %token CHAR_CONST;
%token TOK_INT_CONST; %token INT_CONST;
%token TOK_FLOAT_CONST; %token FLOAT_CONST;
%token TOK_STR_CONST; %token STRING_LITERAL;
%token TOK_IDENTIFIER; %token IDENTIFIER;
%start translation_unit
%% %%
translation_unit : constant
| external_decl : INT_CONST
| translation_unit external_decl | FLOAT_CONST
| CHAR_CONST
; ;
external_decl : function_definition primary_expression
| decl : IDENTIFIER
| constant
| STRING_LITERAL
| LPAREN expression RPAREN
; ;
function_definition : decl_specs declarator decl_list compound_stat postfix_expression
| declarator decl_list compound_stat : primary_expression
| decl_specs declarator compound_stat | postfix_expression LBRACKET expression RBRACKET
| declarator compound_stat | postfix_expression LPAREN RPAREN
| postfix_expression LPAREN argument_expression_list RPAREN
| postfix_expression DOT IDENTIFIER
| postfix_expression ARROW IDENTIFIER
| postfix_expression INCREMENT
| postfix_expression DECREMENT
; ;
decl : decl_specs init_declarator_list TOK_SEMICOLON argument_expression_list
| decl_specs TOK_SEMICOLON : assignment_expression
| argument_expression_list COMMA assignment_expression
; ;
decl_list : decl unary_expression
| decl_list decl : postfix_expression
| INCREMENT unary_expression
| DECREMENT unary_expression
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF LPAREN type_name RPAREN
; ;
decl_specs : storage_class_spec decl_specs unary_operator
| storage_class_spec : BITAND
| type_spec decl_specs | TIMES
| type_spec | PLUS
| type_qualifier decl_specs | MINUS
| BITNOT
| NOT
;
cast_expression
: unary_expression
| LPAREN type_name RPAREN cast_expression
;
multiplicative_expression
: cast_expression
| multiplicative_expression TIMES cast_expression
| multiplicative_expression DIVIDE cast_expression
| multiplicative_expression MOD cast_expression
;
additive_expression
: multiplicative_expression
| additive_expression PLUS multiplicative_expression
| additive_expression MINUS multiplicative_expression
;
shift_expression
: additive_expression
| shift_expression LSHIFT additive_expression
| shift_expression RSHIFT additive_expression
;
relational_expression
: shift_expression
| relational_expression LESS shift_expression
| relational_expression GREATER shift_expression
| relational_expression LESSEQ shift_expression
| relational_expression GREATEREQ shift_expression
;
equality_expression
: relational_expression
| equality_expression EQUALS relational_expression
| equality_expression NOTEQUALS relational_expression
;
and_expression
: equality_expression
| and_expression BITAND equality_expression
;
exclusive_or_expression
: and_expression
| exclusive_or_expression XOR and_expression
;
inclusive_or_expression
: exclusive_or_expression
| inclusive_or_expression BITOR exclusive_or_expression
;
logical_and_expression
: inclusive_or_expression
| logical_and_expression AND inclusive_or_expression
;
logical_or_expression
: logical_and_expression
| logical_or_expression OR logical_and_expression
;
conditional_expression
: logical_or_expression
| logical_or_expression QUESTION expression COLON conditional_expression
;
assignment_expression
: conditional_expression
| unary_expression assignment_operator assignment_expression
;
assignment_operator
: ASSIGN
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;
expression
: assignment_expression
| expression COMMA assignment_expression
;
constant_expression
: conditional_expression
;
declaration
: declaration_specifiers SEMICOLON
| declaration_specifiers init_declarator_list SEMICOLON
;
declaration_specifiers
: storage_class_specifier
| storage_class_specifier declaration_specifiers
| type_specifier
| type_specifier declaration_specifiers
| type_qualifier
| type_qualifier declaration_specifiers
;
init_declarator_list
: init_declarator
| init_declarator_list COMMA init_declarator
;
init_declarator
: declarator
| declarator ASSIGN initializer
;
storage_class_specifier
: TYPEDEF
| EXTERN
| STATIC
| AUTO
| REGISTER
;
type_specifier
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
| struct_or_union_specifier
| enum_specifier
| IDENTIFIER
;
struct_or_union_specifier
: struct_or_union IDENTIFIER LCURLY struct_declaration_list RCURLY
| struct_or_union LCURLY struct_declaration_list RCURLY
| struct_or_union IDENTIFIER
;
struct_or_union
: STRUCT
| UNION
;
struct_declaration_list
: struct_declaration
| struct_declaration_list struct_declaration
;
struct_declaration
: specifier_qualifier_list struct_declarator_list SEMICOLON
;
specifier_qualifier_list
: type_specifier specifier_qualifier_list
| type_specifier
| type_qualifier specifier_qualifier_list
| type_qualifier | type_qualifier
; ;
storage_class_spec : TOK_AUTO | TOK_REGISTER | TOK_STATIC | TOK_EXTERN | TOK_TYPEDEF struct_declarator_list
: struct_declarator
| struct_declarator_list COMMA struct_declarator
; ;
type_spec : TOK_VOID | TOK_CHAR | TOK_SHORT | TOK_INT | TOK_LONG | TOK_FLOAT struct_declarator
| TOK_DOUBLE | TOK_SIGNED | TOK_UNSIGNED : declarator
| struct_or_union_spec | COLON constant_expression
| enum_spec | declarator COLON constant_expression
| typedef_name
; ;
type_qualifier : TOK_CONST | TOK_VOLATILE enum_specifier
: ENUM LCURLY enumerator_list RCURLY
| ENUM IDENTIFIER LCURLY enumerator_list RCURLY
| ENUM IDENTIFIER
; ;
struct_or_union_spec : struct_or_union TOK_IDENTIFIER TOK_LCURLY struct_decl_list TOK_RCURLY enumerator_list
| struct_or_union TOK_LCURLY struct_decl_list TOK_RCURLY : enumerator
| struct_or_union TOK_IDENTIFIER | enumerator_list COMMA enumerator
; ;
struct_or_union : TOK_STRUCT | TOK_UNION enumerator
: IDENTIFIER
| IDENTIFIER ASSIGN constant_expression
; ;
struct_decl_list : struct_decl type_qualifier
| struct_decl_list struct_decl : CONST
| VOLATILE
; ;
init_declarator_list : init_declarator declarator
| init_declarator_list TOK_COMMA init_declarator : pointer direct_declarator
;
init_declarator : declarator
| declarator TOK_ASSIGN initializer
;
struct_decl : spec_qualifier_list struct_declarator_list TOK_SEMICOLON
;
spec_qualifier_list : type_spec spec_qualifier_list
| type_spec
| type_qualifier spec_qualifier_list
| type_qualifier
;
struct_declarator_list : struct_declarator
| struct_declarator_list TOK_COMMA struct_declarator
;
struct_declarator : declarator
| declarator TOK_COLON const_exp
| TOK_COLON const_exp
;
enum_spec : TOK_ENUM TOK_IDENTIFIER TOK_LCURLY enumerator_list TOK_RCURLY
| TOK_ENUM TOK_LCURLY enumerator_list TOK_RCURLY
| TOK_ENUM TOK_IDENTIFIER
;
enumerator_list : enumerator
| enumerator_list TOK_COMMA enumerator
;
enumerator : TOK_IDENTIFIER
| TOK_IDENTIFIER TOK_ASSIGN const_exp
;
declarator : pointer direct_declarator
| direct_declarator | direct_declarator
; ;
direct_declarator : TOK_IDENTIFIER direct_declarator
| TOK_LPAREN declarator TOK_RPAREN : IDENTIFIER
| direct_declarator TOK_LBRACKET const_exp TOK_RBRACKET | LPAREN declarator RPAREN
| direct_declarator TOK_LBRACKET TOK_RBRACKET | direct_declarator LBRACKET constant_expression RBRACKET
| direct_declarator TOK_LPAREN param_type_list TOK_RPAREN | direct_declarator LBRACKET RBRACKET
| direct_declarator TOK_LPAREN id_list TOK_RPAREN | direct_declarator LPAREN parameter_type_list RPAREN
| direct_declarator TOK_LPAREN TOK_RPAREN | direct_declarator LPAREN identifier_list RPAREN
| direct_declarator LPAREN RPAREN
; ;
pointer : TOK_TIMES type_qualifier_list pointer
| TOK_TIMES : TIMES
| TOK_TIMES type_qualifier_list pointer | TIMES type_qualifier_list
| TOK_TIMES pointer | TIMES pointer
| TIMES type_qualifier_list pointer
; ;
type_qualifier_list : type_qualifier type_qualifier_list
: type_qualifier
| type_qualifier_list type_qualifier | type_qualifier_list type_qualifier
; ;
param_type_list : param_list
| param_list TOK_COMMA TOK_ELLIPSES parameter_type_list
: parameter_list
| parameter_list COMMA ELLIPSIS
; ;
param_list : param_decl parameter_list
| param_list TOK_COMMA param_decl : parameter_declaration
| parameter_list COMMA parameter_declaration
; ;
param_decl : decl_specs declarator parameter_declaration
| decl_specs abstract_declarator : declaration_specifiers declarator
| decl_specs | declaration_specifiers abstract_declarator
| declaration_specifiers
; ;
id_list : TOK_IDENTIFIER identifier_list
| id_list TOK_COMMA TOK_IDENTIFIER : IDENTIFIER
| identifier_list COMMA IDENTIFIER
; ;
initializer : assignment_exp type_name
| TOK_LCURLY initializer_list TOK_RCURLY : specifier_qualifier_list
| TOK_LCURLY initializer_list TOK_COMMA TOK_RCURLY | specifier_qualifier_list abstract_declarator
; ;
initializer_list : initializer abstract_declarator
| initializer_list TOK_COMMA initializer : pointer
;
type_name : spec_qualifier_list abstract_declarator
| spec_qualifier_list
;
abstract_declarator : pointer
| pointer direct_abstract_declarator
| direct_abstract_declarator | direct_abstract_declarator
| pointer direct_abstract_declarator
; ;
direct_abstract_declarator: TOK_LPAREN abstract_declarator TOK_RPAREN direct_abstract_declarator
| direct_abstract_declarator TOK_LBRACKET const_exp TOK_RBRACKET : LPAREN abstract_declarator RPAREN
| TOK_LBRACKET const_exp TOK_RBRACKET | LBRACKET RBRACKET
| direct_abstract_declarator TOK_LBRACKET TOK_RBRACKET | LBRACKET constant_expression RBRACKET
| TOK_LBRACKET TOK_RBRACKET | direct_abstract_declarator LBRACKET RBRACKET
| direct_abstract_declarator TOK_LPAREN param_type_list TOK_RPAREN | direct_abstract_declarator LBRACKET constant_expression RBRACKET
| TOK_LPAREN param_type_list TOK_RPAREN | LPAREN RPAREN
| direct_abstract_declarator TOK_LPAREN TOK_RPAREN | LPAREN parameter_type_list RPAREN
| TOK_LPAREN TOK_RPAREN | direct_abstract_declarator LPAREN RPAREN
| direct_abstract_declarator LPAREN parameter_type_list RPAREN
; ;
typedef_name : TOK_IDENTIFIER initializer
: assignment_expression
| LCURLY initializer_list RCURLY
| LCURLY initializer_list COMMA RCURLY
; ;
stat : labeled_stat initializer_list
| exp_stat : initializer
| compound_stat | initializer_list COMMA initializer
| selection_stat
| iteration_stat
| jump_stat
; ;
labeled_stat : TOK_IDENTIFIER TOK_COLON stat statement
| TOK_CASE const_exp TOK_COLON stat : labeled_statement
| TOK_DEFAULT TOK_COLON stat | compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
; ;
exp_stat : exp TOK_SEMICOLON labeled_statement
| TOK_SEMICOLON : IDENTIFIER COLON statement
| CASE constant_expression COLON statement
| DEFAULT COLON statement
; ;
compound_stat : TOK_LCURLY decl_list stat_list TOK_RCURLY compound_statement
| TOK_LCURLY stat_list TOK_RCURLY : LCURLY RCURLY
| TOK_LCURLY decl_list TOK_RCURLY | LCURLY statement_list RCURLY
| TOK_LCURLY TOK_RCURLY | LCURLY declaration_list RCURLY
| LCURLY declaration_list statement_list RCURLY
; ;
stat_list : stat declaration_list
| stat_list stat : declaration
| declaration_list declaration
; ;
selection_stat : TOK_IF TOK_LPAREN exp TOK_RPAREN stat statement_list
| TOK_IF TOK_LPAREN exp TOK_RPAREN stat TOK_ELSE stat : statement
| TOK_SWITCH TOK_LPAREN exp TOK_RPAREN stat | statement_list statement
; ;
iteration_stat : TOK_WHILE TOK_LPAREN exp TOK_RPAREN stat expression_statement
| TOK_DO stat TOK_WHILE TOK_LPAREN exp TOK_RPAREN TOK_SEMICOLON : SEMICOLON
| TOK_FOR TOK_LPAREN exp TOK_SEMICOLON exp TOK_SEMICOLON exp TOK_RPAREN stat | expression SEMICOLON
| TOK_FOR TOK_LPAREN exp TOK_SEMICOLON exp TOK_SEMICOLON TOK_RPAREN stat
| TOK_FOR TOK_LPAREN exp TOK_SEMICOLON TOK_SEMICOLON exp TOK_RPAREN stat
| TOK_FOR TOK_LPAREN exp TOK_SEMICOLON TOK_SEMICOLON TOK_RPAREN stat
| TOK_FOR TOK_LPAREN TOK_SEMICOLON exp TOK_SEMICOLON exp TOK_RPAREN stat
| TOK_FOR TOK_LPAREN TOK_SEMICOLON exp TOK_SEMICOLON TOK_RPAREN stat
| TOK_FOR TOK_LPAREN TOK_SEMICOLON TOK_SEMICOLON exp TOK_RPAREN stat
| TOK_FOR TOK_LPAREN TOK_SEMICOLON TOK_SEMICOLON TOK_RPAREN stat
; ;
jump_stat : TOK_GOTO TOK_IDENTIFIER TOK_SEMICOLON selection_statement
| TOK_CONTINUE TOK_SEMICOLON : IF LPAREN expression RPAREN statement
| TOK_BREAK TOK_SEMICOLON | IF LPAREN expression RPAREN statement ELSE statement
| TOK_RETURN exp TOK_SEMICOLON | SWITCH LPAREN expression RPAREN statement
| TOK_RETURN TOK_SEMICOLON
; ;
exp : assignment_exp iteration_statement
| exp TOK_COMMA assignment_exp : WHILE LPAREN expression RPAREN statement
| DO statement WHILE LPAREN expression RPAREN SEMICOLON
| FOR LPAREN expression_statement expression_statement RPAREN statement
| FOR LPAREN expression_statement expression_statement expression RPAREN statement
; ;
assignment_exp : conditional_exp jump_statement
| unary_exp assignment_operator assignment_exp : GOTO IDENTIFIER SEMICOLON
| CONTINUE SEMICOLON
| BREAK SEMICOLON
| RETURN SEMICOLON
| RETURN expression SEMICOLON
; ;
assignment_operator : TOK_ASSIGN | TOK_TIMESEQUALS | TOK_DIVIDEEQUALS | TOK_MODEQUALS | TOK_PLUSEQUALS | TOK_MINUSEQUALS | TOK_LSHIFTEQUALS translation_unit
| TOK_RSHIFTEQUALS | TOK_BITANDEQUALS | TOK_XOREQUALS | TOK_BITOREQUALS : external_declaration
| translation_unit external_declaration
; ;
conditional_exp : logical_or_exp external_declaration
| logical_or_exp TOK_QUESTION exp TOK_COLON conditional_exp : function_definition
| declaration
; ;
const_exp : conditional_exp function_definition
; : declaration_specifiers declarator declaration_list compound_statement
| declaration_specifiers declarator compound_statement
logical_or_exp : logical_and_exp | declarator declaration_list compound_statement
| logical_or_exp TOK_OR logical_and_exp | declarator compound_statement
;
logical_and_exp : inclusive_or_exp
| logical_and_exp TOK_AND inclusive_or_exp
;
inclusive_or_exp : exclusive_or_exp
| inclusive_or_exp TOK_BITOR exclusive_or_exp
;
exclusive_or_exp : and_exp
| exclusive_or_exp TOK_XOR and_exp
;
and_exp : equality_exp
| and_exp TOK_BITAND equality_exp
;
equality_exp : relational_exp
| equality_exp TOK_EQUALS relational_exp
| equality_exp TOK_NOTEQUALS relational_exp
;
relational_exp : shift_expression
| relational_exp TOK_LESS shift_expression
| relational_exp TOK_GREATER shift_expression
| relational_exp TOK_LESSEQ shift_expression
| relational_exp TOK_GREATEREQ shift_expression
;
shift_expression : additive_exp
| shift_expression TOK_LSHIFT additive_exp
| shift_expression TOK_RSHIFT additive_exp
;
additive_exp : mult_exp
| additive_exp TOK_PLUS mult_exp
| additive_exp TOK_MINUS mult_exp
;
mult_exp : cast_exp
| mult_exp TOK_TIMES cast_exp
| mult_exp TOK_DIVIDE cast_exp
| mult_exp TOK_MOD cast_exp
;
cast_exp : unary_exp
| TOK_LPAREN type_name TOK_RPAREN cast_exp
;
unary_exp : postfix_exp
| TOK_INCREMENT unary_exp
| TOK_DECREMENT unary_exp
| unary_operator cast_exp
| TOK_SIZEOF unary_exp
| TOK_SIZEOF TOK_LPAREN type_name TOK_RPAREN
;
unary_operator : TOK_BITAND | TOK_TIMES | TOK_PLUS | TOK_MINUS | TOK_BITNOT | TOK_NOT
;
postfix_exp : primary_exp
| postfix_exp TOK_LBRACKET exp TOK_RBRACKET
| postfix_exp TOK_LPAREN argument_exp_list TOK_RPAREN
| postfix_exp TOK_LPAREN TOK_RPAREN
| postfix_exp TOK_DOT TOK_IDENTIFIER
| postfix_exp TOK_ARROW TOK_IDENTIFIER
| postfix_exp TOK_INCREMENT
| postfix_exp TOK_DECREMENT
;
primary_exp : const
| TOK_STR_CONST
| TOK_LPAREN exp TOK_RPAREN
;
argument_exp_list : assignment_exp
| argument_exp_list TOK_COMMA assignment_exp
;
const : TOK_INT_CONST
| TOK_CHAR_CONST
| TOK_FLOAT_CONST
| TOK_IDENTIFIER
; ;
%% %%