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

View File

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