%lex
%options flex
/* port the character classes from flex */
/* mostly the same except for char literals */
D [0-9]
L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS ('f'|'F'|'l'|'L')
IS ('u'|'U'|'l'|'L')*
%%
'/*' comment(this)
'auto' return 'AUTO'
'break' return 'BREAK'
'case' return 'CASE'
'char' return 'CHAR'
'const' return 'CONST'
'continue' return 'CONTINUE'
'default' return 'DEFAULT'
'do' return 'DO'
'double' return 'DOUBLE'
'else' return 'ELSE'
'enum' return 'ENUM'
'extern' return 'EXTERN'
'float' return 'FLOAT'
'for' return 'FOR'
'goto' return 'GOTO'
'if' return 'IF'
'int' return 'INT'
'long' return 'LONG'
'register' return 'REGISTER'
'return' return 'RETURN'
'short' return 'SHORT'
'signed' return 'SIGNED'
'sizeof' return 'SIZEOF'
'static' return 'STATIC'
'struct' return 'STRUCT'
'switch' return 'SWITCH'
'typedef' return 'TYPEDEF'
'union' return 'UNION'
'unsigned' return 'UNSIGNED'
'void' return 'VOID'
'volatile' return 'VOLATILE'
'while' return 'WHILE'
{L}({L}|{D})* return is_type(pdata, yytext) ? 'TYPE_NAME' : 'IDENTIFIER';
0[xX]{H}+{IS}? return 'CONSTANT'
0{D}+{IS}? return 'CONSTANT'
{D}+{IS}? return 'CONSTANT'
L?'(\.|[^\'])+' return 'CONSTANT'
{D}+{E}{FS}? return 'CONSTANT'
{D}*"."{D}+({E})?{FS}? return 'CONSTANT'
{D}+"."{D}*({E})?{FS}? return 'CONSTANT'
L?\"(\\.|[^\\"])*\" return 'STRING_LITERAL';
"..." return 'ELLIPSIS'
">>=" return 'RIGHT_ASSIGN'
"<<=" return 'LEFT_ASSIGN'
"+=" return 'ADD_ASSIGN'
"-=" return 'SUB_ASSIGN'
"*=" return 'MUL_ASSIGN'
"/=" return 'DIV_ASSIGN'
"%=" return 'MOD_ASSIGN'
"&=" return 'AND_ASSIGN'
"^=" return 'XOR_ASSIGN'
"|=" return 'OR_ASSIGN'
">>" return 'RIGHT_OP'
"<<" return 'LEFT_OP'
"++" return 'INC_OP'
"--" return 'DEC_OP'
"->" return 'PTR_OP'
"&&" return 'AND_OP'
"||" return 'OR_OP'
"<=" return 'LE_OP'
">=" return 'GE_OP'
"==" return 'EQ_OP'
"!=" return 'NE_OP'
";" return ';'
("{"|"<%") return '{'
("}"|"%>") return '}'
"," return ','
":" return ':'
"=" return '='
"(" return '('
")" return ')'
("["|"<:") return '['
("]"|":>") return ']'
"." return '.'
"&" return '&'
"!" return '!'
"~" return '~'
"-" return '-'
'+' return '+'
"*" return '*'
"/" return '/'
"%" return '%'
"<" return '<'
">" return '>'
"^" return '^'
"|" return '|'
"?" return '?'
[ \t\v\n\f] /* ignore ws */
. /* ignore bad chars */
/lex
%start top_level
%lex-param pdata
%parse-param pdata
%% /* language grammar */
top_level
: translation_unit { return $1; }
;
/* AUTOGEN SECTION */
primary_expression
: IDENTIFIER { $$ = make_node(pdata, "primary_expression.0"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); }
| CONSTANT { $$ = make_node(pdata, "primary_expression.1"); node_add_leaf(pdata, $$, 'CONSTANT', @1); }
| STRING_LITERAL { $$ = make_node(pdata, "primary_expression.2"); node_add_leaf(pdata, $$, 'STRING_LITERAL', @1); }
| '(' expression ')' { $$ = make_node(pdata, "primary_expression.3"); node_add_leaf(pdata, $$, '(', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ')', @3); }
;
postfix_expression
: primary_expression
| postfix_expression '[' expression ']' { $$ = make_node(pdata, "postfix_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '[', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ']', @4); }
| postfix_expression '(' ')' { $$ = make_node(pdata, "postfix_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_leaf(pdata, $$, ')', @3); }
| postfix_expression '(' argument_expression_list ')' { $$ = make_node(pdata, "postfix_expression.3"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); }
| postfix_expression '.' IDENTIFIER { $$ = make_node(pdata, "postfix_expression.4"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '.', @2); node_add_leaf(pdata, $$, 'IDENTIFIER', @3); }
| postfix_expression PTR_OP IDENTIFIER { $$ = make_node(pdata, "postfix_expression.5"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'PTR_OP', @2); node_add_leaf(pdata, $$, 'IDENTIFIER', @3); }
| postfix_expression INC_OP { $$ = make_node(pdata, "postfix_expression.6"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'INC_OP', @2); }
| postfix_expression DEC_OP { $$ = make_node(pdata, "postfix_expression.7"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'DEC_OP', @2); }
;
argument_expression_list
: assignment_expression
| argument_expression_list ',' assignment_expression { $$ = make_node(pdata, "argument_expression_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
unary_expression
: postfix_expression
| INC_OP unary_expression { $$ = make_node(pdata, "unary_expression.1"); node_add_leaf(pdata, $$, 'INC_OP', @1); node_add_child(pdata, $$, $2); }
| DEC_OP unary_expression { $$ = make_node(pdata, "unary_expression.2"); node_add_leaf(pdata, $$, 'DEC_OP', @1); node_add_child(pdata, $$, $2); }
| unary_operator cast_expression { $$ = make_node(pdata, "unary_expression.3"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| SIZEOF unary_expression { $$ = make_node(pdata, "unary_expression.4"); node_add_leaf(pdata, $$, 'SIZEOF', @1); node_add_child(pdata, $$, $2); }
| SIZEOF '(' type_name ')' { $$ = make_node(pdata, "unary_expression.5"); node_add_leaf(pdata, $$, 'SIZEOF', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); }
;
unary_operator
: '&' { $$ = make_node(pdata, "unary_operator.0"); node_add_leaf(pdata, $$, '&', @1); }
| '*' { $$ = make_node(pdata, "unary_operator.1"); node_add_leaf(pdata, $$, '*', @1); }
| '+' { $$ = make_node(pdata, "unary_operator.2"); node_add_leaf(pdata, $$, '+', @1); }
| '-' { $$ = make_node(pdata, "unary_operator.3"); node_add_leaf(pdata, $$, '-', @1); }
| '~' { $$ = make_node(pdata, "unary_operator.4"); node_add_leaf(pdata, $$, '~', @1); }
| '!' { $$ = make_node(pdata, "unary_operator.5"); node_add_leaf(pdata, $$, '!', @1); }
;
cast_expression
: unary_expression
| '(' type_name ')' cast_expression { $$ = make_node(pdata, "cast_expression.1"); node_add_leaf(pdata, $$, '(', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ')', @3); node_add_child(pdata, $$, $4); }
;
multiplicative_expression
: cast_expression
| multiplicative_expression '*' cast_expression { $$ = make_node(pdata, "multiplicative_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '*', @2); node_add_child(pdata, $$, $3); }
| multiplicative_expression '/' cast_expression { $$ = make_node(pdata, "multiplicative_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '/', @2); node_add_child(pdata, $$, $3); }
| multiplicative_expression '%' cast_expression { $$ = make_node(pdata, "multiplicative_expression.3"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '%', @2); node_add_child(pdata, $$, $3); }
;
additive_expression
: multiplicative_expression
| additive_expression '+' multiplicative_expression { $$ = make_node(pdata, "additive_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '+', @2); node_add_child(pdata, $$, $3); }
| additive_expression '-' multiplicative_expression { $$ = make_node(pdata, "additive_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '-', @2); node_add_child(pdata, $$, $3); }
;
shift_expression
: additive_expression
| shift_expression LEFT_OP additive_expression { $$ = make_node(pdata, "shift_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'LEFT_OP', @2); node_add_child(pdata, $$, $3); }
| shift_expression RIGHT_OP additive_expression { $$ = make_node(pdata, "shift_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'RIGHT_OP', @2); node_add_child(pdata, $$, $3); }
;
relational_expression
: shift_expression
| relational_expression '<' shift_expression { $$ = make_node(pdata, "relational_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '<', @2); node_add_child(pdata, $$, $3); }
| relational_expression '>' shift_expression { $$ = make_node(pdata, "relational_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '>', @2); node_add_child(pdata, $$, $3); }
| relational_expression LE_OP shift_expression { $$ = make_node(pdata, "relational_expression.3"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'LE_OP', @2); node_add_child(pdata, $$, $3); }
| relational_expression GE_OP shift_expression { $$ = make_node(pdata, "relational_expression.4"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'GE_OP', @2); node_add_child(pdata, $$, $3); }
;
equality_expression
: relational_expression
| equality_expression EQ_OP relational_expression { $$ = make_node(pdata, "equality_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'EQ_OP', @2); node_add_child(pdata, $$, $3); }
| equality_expression NE_OP relational_expression { $$ = make_node(pdata, "equality_expression.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'NE_OP', @2); node_add_child(pdata, $$, $3); }
;
and_expression
: equality_expression
| and_expression '&' equality_expression { $$ = make_node(pdata, "and_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '&', @2); node_add_child(pdata, $$, $3); }
;
exclusive_or_expression
: and_expression
| exclusive_or_expression '^' and_expression { $$ = make_node(pdata, "exclusive_or_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '^', @2); node_add_child(pdata, $$, $3); }
;
inclusive_or_expression
: exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression { $$ = make_node(pdata, "inclusive_or_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '|', @2); node_add_child(pdata, $$, $3); }
;
logical_and_expression
: inclusive_or_expression
| logical_and_expression AND_OP inclusive_or_expression { $$ = make_node(pdata, "logical_and_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'AND_OP', @2); node_add_child(pdata, $$, $3); }
;
logical_or_expression
: logical_and_expression
| logical_or_expression OR_OP logical_and_expression { $$ = make_node(pdata, "logical_or_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'OR_OP', @2); node_add_child(pdata, $$, $3); }
;
conditional_expression
: logical_or_expression
| logical_or_expression '?' expression ':' conditional_expression { $$ = make_node(pdata, "conditional_expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '?', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ':', @4); node_add_child(pdata, $$, $5); }
;
assignment_expression
: conditional_expression
| unary_expression assignment_operator assignment_expression { $$ = make_node(pdata, "assignment_expression.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); }
;
assignment_operator
: '=' { $$ = make_node(pdata, "assignment_operator.0"); node_add_leaf(pdata, $$, '=', @1); }
| MUL_ASSIGN { $$ = make_node(pdata, "assignment_operator.1"); node_add_leaf(pdata, $$, 'MUL_ASSIGN', @1); }
| DIV_ASSIGN { $$ = make_node(pdata, "assignment_operator.2"); node_add_leaf(pdata, $$, 'DIV_ASSIGN', @1); }
| MOD_ASSIGN { $$ = make_node(pdata, "assignment_operator.3"); node_add_leaf(pdata, $$, 'MOD_ASSIGN', @1); }
| ADD_ASSIGN { $$ = make_node(pdata, "assignment_operator.4"); node_add_leaf(pdata, $$, 'ADD_ASSIGN', @1); }
| SUB_ASSIGN { $$ = make_node(pdata, "assignment_operator.5"); node_add_leaf(pdata, $$, 'SUB_ASSIGN', @1); }
| LEFT_ASSIGN { $$ = make_node(pdata, "assignment_operator.6"); node_add_leaf(pdata, $$, 'LEFT_ASSIGN', @1); }
| RIGHT_ASSIGN { $$ = make_node(pdata, "assignment_operator.7"); node_add_leaf(pdata, $$, 'RIGHT_ASSIGN', @1); }
| AND_ASSIGN { $$ = make_node(pdata, "assignment_operator.8"); node_add_leaf(pdata, $$, 'AND_ASSIGN', @1); }
| XOR_ASSIGN { $$ = make_node(pdata, "assignment_operator.9"); node_add_leaf(pdata, $$, 'XOR_ASSIGN', @1); }
| OR_ASSIGN { $$ = make_node(pdata, "assignment_operator.10"); node_add_leaf(pdata, $$, 'OR_ASSIGN', @1); }
;
expression
: assignment_expression
| expression ',' assignment_expression { $$ = make_node(pdata, "expression.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
constant_expression
: conditional_expression { $$ = make_node(pdata, "constant_expression.0"); node_add_child(pdata, $$, $1); }
;
declaration
: declaration_specifiers ';' { $$ = make_node(pdata, "declaration.0"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ';', @2); check_declaration(pdata, $$);}
| declaration_specifiers init_declarator_list ';' { $$ = make_node(pdata, "declaration.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ';', @3); check_declaration(pdata, $$);}
;
declaration_specifiers
: storage_class_specifier { $$ = make_node(pdata, "declaration_specifiers.0"); node_add_child(pdata, $$, $1); }
| storage_class_specifier declaration_specifiers { $$ = make_node(pdata, "declaration_specifiers.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| type_specifier { $$ = make_node(pdata, "declaration_specifiers.2"); node_add_child(pdata, $$, $1); }
| type_specifier declaration_specifiers { $$ = make_node(pdata, "declaration_specifiers.3"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| type_qualifier { $$ = make_node(pdata, "declaration_specifiers.4"); node_add_child(pdata, $$, $1); }
| type_qualifier declaration_specifiers { $$ = make_node(pdata, "declaration_specifiers.5"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
;
init_declarator_list
: init_declarator { $$ = make_node(pdata, "init_declarator_list.0"); node_add_child(pdata, $$, $1); }
| init_declarator_list ',' init_declarator { $$ = make_node(pdata, "init_declarator_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
init_declarator
: declarator { $$ = make_node(pdata, "init_declarator.0"); node_add_child(pdata, $$, $1); }
| declarator '=' initializer { $$ = make_node(pdata, "init_declarator.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '=', @2); node_add_child(pdata, $$, $3); }
;
storage_class_specifier
: TYPEDEF { $$ = make_node(pdata, "storage_class_specifier.0"); node_add_leaf(pdata, $$, 'TYPEDEF', @1); }
| EXTERN { $$ = make_node(pdata, "storage_class_specifier.1"); node_add_leaf(pdata, $$, 'EXTERN', @1); }
| STATIC { $$ = make_node(pdata, "storage_class_specifier.2"); node_add_leaf(pdata, $$, 'STATIC', @1); }
| AUTO { $$ = make_node(pdata, "storage_class_specifier.3"); node_add_leaf(pdata, $$, 'AUTO', @1); }
| REGISTER { $$ = make_node(pdata, "storage_class_specifier.4"); node_add_leaf(pdata, $$, 'REGISTER', @1); }
;
type_specifier
: VOID { $$ = make_node(pdata, "type_specifier.0"); node_add_leaf(pdata, $$, 'VOID', @1); }
| CHAR { $$ = make_node(pdata, "type_specifier.1"); node_add_leaf(pdata, $$, 'CHAR', @1); }
| SHORT { $$ = make_node(pdata, "type_specifier.2"); node_add_leaf(pdata, $$, 'SHORT', @1); }
| INT { $$ = make_node(pdata, "type_specifier.3"); node_add_leaf(pdata, $$, 'INT', @1); }
| LONG { $$ = make_node(pdata, "type_specifier.4"); node_add_leaf(pdata, $$, 'LONG', @1); }
| FLOAT { $$ = make_node(pdata, "type_specifier.5"); node_add_leaf(pdata, $$, 'FLOAT', @1); }
| DOUBLE { $$ = make_node(pdata, "type_specifier.6"); node_add_leaf(pdata, $$, 'DOUBLE', @1); }
| SIGNED { $$ = make_node(pdata, "type_specifier.7"); node_add_leaf(pdata, $$, 'SIGNED', @1); }
| UNSIGNED { $$ = make_node(pdata, "type_specifier.8"); node_add_leaf(pdata, $$, 'UNSIGNED', @1); }
| struct_or_union_specifier { $$ = make_node(pdata, "type_specifier.9"); node_add_child(pdata, $$, $1); }
| enum_specifier { $$ = make_node(pdata, "type_specifier.10"); node_add_child(pdata, $$, $1); }
| TYPE_NAME { $$ = make_node(pdata, "type_specifier.11"); node_add_leaf(pdata, $$, 'TYPE_NAME', @1); }
;
struct_or_union_specifier
: struct_or_union IDENTIFIER '{' struct_declaration_list '}' { $$ = make_node(pdata, "struct_or_union_specifier.0"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'IDENTIFIER', @2); node_add_leaf(pdata, $$, '{', @3); node_add_child(pdata, $$, $4); node_add_leaf(pdata, $$, '}', @5); }
| struct_or_union '{' struct_declaration_list '}' { $$ = make_node(pdata, "struct_or_union_specifier.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '{', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, '}', @4); }
| struct_or_union IDENTIFIER { $$ = make_node(pdata, "struct_or_union_specifier.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, 'IDENTIFIER', @2); }
;
struct_or_union
: STRUCT { $$ = make_node(pdata, "struct_or_union.0"); node_add_leaf(pdata, $$, 'STRUCT', @1); }
| UNION { $$ = make_node(pdata, "struct_or_union.1"); node_add_leaf(pdata, $$, 'UNION', @1); }
;
struct_declaration_list
: struct_declaration { $$ = make_node(pdata, "struct_declaration_list.0"); node_add_child(pdata, $$, $1); }
| struct_declaration_list struct_declaration { $$ = $1; node_add_child(pdata, $$, $2); }
;
struct_declaration
: specifier_qualifier_list struct_declarator_list ';' { $$ = make_node(pdata, "struct_declaration.0"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ';', @3); }
;
specifier_qualifier_list
: type_specifier specifier_qualifier_list { $$ = make_node(pdata, "specifier_qualifier_list.0"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| type_specifier { $$ = make_node(pdata, "specifier_qualifier_list.1"); node_add_child(pdata, $$, $1); }
| type_qualifier specifier_qualifier_list { $$ = make_node(pdata, "specifier_qualifier_list.2"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| type_qualifier { $$ = make_node(pdata, "specifier_qualifier_list.3"); node_add_child(pdata, $$, $1); }
;
struct_declarator_list
: struct_declarator { $$ = make_node(pdata, "struct_declarator_list.0"); node_add_child(pdata, $$, $1); }
| struct_declarator_list ',' struct_declarator { $$ = make_node(pdata, "struct_declarator_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
struct_declarator
: declarator { $$ = make_node(pdata, "struct_declarator.0"); node_add_child(pdata, $$, $1); }
| ':' constant_expression { $$ = make_node(pdata, "struct_declarator.1"); node_add_leaf(pdata, $$, ':', @1); node_add_child(pdata, $$, $2); }
| declarator ':' constant_expression { $$ = make_node(pdata, "struct_declarator.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ':', @2); node_add_child(pdata, $$, $3); }
;
enum_specifier
: ENUM '{' enumerator_list '}' { $$ = make_node(pdata, "enum_specifier.0"); node_add_leaf(pdata, $$, 'ENUM', @1); node_add_leaf(pdata, $$, '{', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, '}', @4); }
| ENUM IDENTIFIER '{' enumerator_list '}' { $$ = make_node(pdata, "enum_specifier.1"); node_add_leaf(pdata, $$, 'ENUM', @1); node_add_leaf(pdata, $$, 'IDENTIFIER', @2); node_add_leaf(pdata, $$, '{', @3); node_add_child(pdata, $$, $4); node_add_leaf(pdata, $$, '}', @5); }
| ENUM IDENTIFIER { $$ = make_node(pdata, "enum_specifier.2"); node_add_leaf(pdata, $$, 'ENUM', @1); node_add_leaf(pdata, $$, 'IDENTIFIER', @2); }
;
enumerator_list
: enumerator { $$ = make_node(pdata, "enumerator_list.0"); node_add_child(pdata, $$, $1); }
| enumerator_list ',' enumerator { $$ = make_node(pdata, "enumerator_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
enumerator
: IDENTIFIER { $$ = make_node(pdata, "enumerator.0"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); }
| IDENTIFIER '=' constant_expression { $$ = make_node(pdata, "enumerator.1"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); node_add_leaf(pdata, $$, '=', @2); node_add_child(pdata, $$, $3); }
;
type_qualifier
: CONST { $$ = make_node(pdata, "type_qualifier.0"); node_add_leaf(pdata, $$, 'CONST', @1); }
| VOLATILE { $$ = make_node(pdata, "type_qualifier.1"); node_add_leaf(pdata, $$, 'VOLATILE', @1); }
;
declarator
: pointer direct_declarator { $$ = make_node(pdata, "declarator.0"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| direct_declarator { $$ = make_node(pdata, "declarator.1"); node_add_child(pdata, $$, $1); }
;
direct_declarator
: IDENTIFIER { $$ = make_node(pdata, "direct_declarator.0"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); }
| '(' declarator ')' { $$ = make_node(pdata, "direct_declarator.1"); node_add_leaf(pdata, $$, '(', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ')', @3); }
| direct_declarator '[' constant_expression ']' { $$ = make_node(pdata, "direct_declarator.2"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '[', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ']', @4); }
| direct_declarator '[' ']' { $$ = make_node(pdata, "direct_declarator.3"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '[', @2); node_add_leaf(pdata, $$, ']', @3); }
| direct_declarator '(' parameter_type_list ')' { $$ = make_node(pdata, "direct_declarator.4"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); }
| direct_declarator '(' identifier_list ')' { $$ = make_node(pdata, "direct_declarator.5"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); }
| direct_declarator '(' ')' { $$ = make_node(pdata, "direct_declarator.6"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_leaf(pdata, $$, ')', @3); }
;
pointer
: '*' { $$ = make_node(pdata, "pointer.0"); node_add_leaf(pdata, $$, '*', @1); }
| '*' type_qualifier_list { $$ = make_node(pdata, "pointer.1"); node_add_leaf(pdata, $$, '*', @1); node_add_child(pdata, $$, $2); }
| '*' pointer { $$ = make_node(pdata, "pointer.2"); node_add_leaf(pdata, $$, '*', @1); node_add_child(pdata, $$, $2); }
| '*' type_qualifier_list pointer { $$ = make_node(pdata, "pointer.3"); node_add_leaf(pdata, $$, '*', @1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); }
;
type_qualifier_list
: type_qualifier { $$ = make_node(pdata, "type_qualifier_list.0"); node_add_child(pdata, $$, $1); }
| type_qualifier_list type_qualifier { $$ = make_node(pdata, "type_qualifier_list.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
;
parameter_type_list
: parameter_list { $$ = make_node(pdata, "parameter_type_list.0"); node_add_child(pdata, $$, $1); }
| parameter_list ',' ELLIPSIS { $$ = make_node(pdata, "parameter_type_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_leaf(pdata, $$, 'ELLIPSIS', @3); }
;
parameter_list
: parameter_declaration { $$ = make_node(pdata, "parameter_list.0"); node_add_child(pdata, $$, $1); }
| parameter_list ',' parameter_declaration { $$ = $1; node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
parameter_declaration
: declaration_specifiers declarator { $$ = make_node(pdata, "parameter_declaration.0"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| declaration_specifiers abstract_declarator { $$ = make_node(pdata, "parameter_declaration.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
| declaration_specifiers { $$ = make_node(pdata, "parameter_declaration.2"); node_add_child(pdata, $$, $1); }
;
identifier_list
: IDENTIFIER { $$ = make_node(pdata, "identifier_list.0"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); }
| identifier_list ',' IDENTIFIER { $$ = make_node(pdata, "identifier_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_leaf(pdata, $$, 'IDENTIFIER', @3); }
;
type_name
: specifier_qualifier_list { $$ = make_node(pdata, "type_name.0"); node_add_child(pdata, $$, $1); }
| specifier_qualifier_list abstract_declarator { $$ = make_node(pdata, "type_name.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
;
abstract_declarator
: pointer { $$ = make_node(pdata, "abstract_declarator.0"); node_add_child(pdata, $$, $1); }
| direct_abstract_declarator { $$ = make_node(pdata, "abstract_declarator.1"); node_add_child(pdata, $$, $1); }
| pointer direct_abstract_declarator { $$ = make_node(pdata, "abstract_declarator.2"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
;
direct_abstract_declarator
: '(' abstract_declarator ')' { $$ = make_node(pdata, "direct_abstract_declarator.0"); node_add_leaf(pdata, $$, '(', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ')', @3); }
| '[' ']' { $$ = make_node(pdata, "direct_abstract_declarator.1"); node_add_leaf(pdata, $$, '[', @1); node_add_leaf(pdata, $$, ']', @2); }
| '[' constant_expression ']' { $$ = make_node(pdata, "direct_abstract_declarator.2"); node_add_leaf(pdata, $$, '[', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ']', @3); }
| direct_abstract_declarator '[' ']' { $$ = make_node(pdata, "direct_abstract_declarator.3"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '[', @2); node_add_leaf(pdata, $$, ']', @3); }
| direct_abstract_declarator '[' constant_expression ']' { $$ = make_node(pdata, "direct_abstract_declarator.4"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '[', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ']', @4); }
| '(' ')' { $$ = make_node(pdata, "direct_abstract_declarator.5"); node_add_leaf(pdata, $$, '(', @1); node_add_leaf(pdata, $$, ')', @2); }
| '(' parameter_type_list ')' { $$ = make_node(pdata, "direct_abstract_declarator.6"); node_add_leaf(pdata, $$, '(', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ')', @3); }
| direct_abstract_declarator '(' ')' { $$ = make_node(pdata, "direct_abstract_declarator.7"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_leaf(pdata, $$, ')', @3); }
| direct_abstract_declarator '(' parameter_type_list ')' { $$ = make_node(pdata, "direct_abstract_declarator.8"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); }
;
initializer
: assignment_expression { $$ = make_node(pdata, "initializer.0"); node_add_child(pdata, $$, $1); }
| '{' initializer_list '}' { $$ = make_node(pdata, "initializer.1"); node_add_leaf(pdata, $$, '{', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, '}', @3); }
| '{' initializer_list ',' '}' { $$ = make_node(pdata, "initializer.2"); node_add_leaf(pdata, $$, '{', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ',', @3); node_add_leaf(pdata, $$, '}', @4); }
;
initializer_list
: initializer { $$ = make_node(pdata, "initializer_list.0"); node_add_child(pdata, $$, $1); }
| initializer_list ',' initializer { $$ = make_node(pdata, "initializer_list.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ',', @2); node_add_child(pdata, $$, $3); }
;
statement
: labeled_statement { $$ = make_node(pdata, "statement.0"); node_add_child(pdata, $$, $1); }
| compound_statement { $$ = make_node(pdata, "statement.1"); node_add_child(pdata, $$, $1); }
| expression_statement { $$ = make_node(pdata, "statement.2"); node_add_child(pdata, $$, $1); }
| selection_statement { $$ = make_node(pdata, "statement.3"); node_add_child(pdata, $$, $1); }
| iteration_statement { $$ = make_node(pdata, "statement.4"); node_add_child(pdata, $$, $1); }
| jump_statement { $$ = make_node(pdata, "statement.5"); node_add_child(pdata, $$, $1); }
;
labeled_statement
: IDENTIFIER ':' statement { $$ = make_node(pdata, "labeled_statement.0"); node_add_leaf(pdata, $$, 'IDENTIFIER', @1); node_add_leaf(pdata, $$, ':', @2); node_add_child(pdata, $$, $3); }
| CASE constant_expression ':' statement { $$ = make_node(pdata, "labeled_statement.1"); node_add_leaf(pdata, $$, 'CASE', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ':', @3); node_add_child(pdata, $$, $4); }
| DEFAULT ':' statement { $$ = make_node(pdata, "labeled_statement.2"); node_add_leaf(pdata, $$, 'DEFAULT', @1); node_add_leaf(pdata, $$, ':', @2); node_add_child(pdata, $$, $3); }
;
compound_statement
: '{' '}' { $$ = make_node(pdata, "compound_statement.0"); node_add_leaf(pdata, $$, '{', @1); node_add_leaf(pdata, $$, '}', @2); }
| '{' statement_list '}' { $$ = make_node(pdata, "compound_statement.1"); node_add_leaf(pdata, $$, '{', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, '}', @3); }
| '{' declaration_list '}' { $$ = make_node(pdata, "compound_statement.2"); node_add_leaf(pdata, $$, '{', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, '}', @3); }
| '{' declaration_list statement_list '}' { $$ = make_node(pdata, "compound_statement.3"); node_add_leaf(pdata, $$, '{', @1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, '}', @4); }
;
declaration_list
: declaration { $$ = make_node(pdata, "declaration_list.0"); node_add_child(pdata, $$, $1); }
| declaration_list declaration { $$ = $1; node_add_child(pdata, $$, $2); }
;
statement_list
: statement { $$ = make_node(pdata, "statement_list.0"); node_add_child(pdata, $$, $1); }
| statement_list statement { $$ = $1; node_add_child(pdata, $$, $2); }
;
expression_statement
: ';' { $$ = make_node(pdata, "expression_statement.0"); node_add_leaf(pdata, $$, ';', @1); }
| expression ';' { $$ = make_node(pdata, "expression_statement.1"); node_add_child(pdata, $$, $1); node_add_leaf(pdata, $$, ';', @2); }
;
selection_statement
: IF '(' expression ')' statement { $$ = make_node(pdata, "selection_statement.0"); node_add_leaf(pdata, $$, 'IF', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); node_add_child(pdata, $$, $5); }
| IF '(' expression ')' statement ELSE statement { $$ = make_node(pdata, "selection_statement.1"); node_add_leaf(pdata, $$, 'IF', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); node_add_child(pdata, $$, $5); node_add_leaf(pdata, $$, 'ELSE', @6); node_add_child(pdata, $$, $7); }
| SWITCH '(' expression ')' statement { $$ = make_node(pdata, "selection_statement.2"); node_add_leaf(pdata, $$, 'SWITCH', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); node_add_child(pdata, $$, $5); }
;
iteration_statement
: WHILE '(' expression ')' statement { $$ = make_node(pdata, "iteration_statement.0"); node_add_leaf(pdata, $$, 'WHILE', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_leaf(pdata, $$, ')', @4); node_add_child(pdata, $$, $5); }
| DO statement WHILE '(' expression ')' ';' { $$ = make_node(pdata, "iteration_statement.1"); node_add_leaf(pdata, $$, 'DO', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, 'WHILE', @3); node_add_leaf(pdata, $$, '(', @4); node_add_child(pdata, $$, $5); node_add_leaf(pdata, $$, ')', @6); node_add_leaf(pdata, $$, ';', @7); }
| FOR '(' expression_statement expression_statement ')' statement { $$ = make_node(pdata, "iteration_statement.2"); node_add_leaf(pdata, $$, 'FOR', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_child(pdata, $$, $4); node_add_leaf(pdata, $$, ')', @5); node_add_child(pdata, $$, $6); }
| FOR '(' expression_statement expression_statement expression ')' statement { $$ = make_node(pdata, "iteration_statement.3"); node_add_leaf(pdata, $$, 'FOR', @1); node_add_leaf(pdata, $$, '(', @2); node_add_child(pdata, $$, $3); node_add_child(pdata, $$, $4); node_add_child(pdata, $$, $5); node_add_leaf(pdata, $$, ')', @6); node_add_child(pdata, $$, $7); }
;
jump_statement
: GOTO IDENTIFIER ';' { $$ = make_node(pdata, "jump_statement.0"); node_add_leaf(pdata, $$, 'GOTO', @1); node_add_leaf(pdata, $$, 'IDENTIFIER', @2); node_add_leaf(pdata, $$, ';', @3); }
| CONTINUE ';' { $$ = make_node(pdata, "jump_statement.1"); node_add_leaf(pdata, $$, 'CONTINUE', @1); node_add_leaf(pdata, $$, ';', @2); }
| BREAK ';' { $$ = make_node(pdata, "jump_statement.2"); node_add_leaf(pdata, $$, 'BREAK', @1); node_add_leaf(pdata, $$, ';', @2); }
| RETURN ';' { $$ = make_node(pdata, "jump_statement.3"); node_add_leaf(pdata, $$, 'RETURN', @1); node_add_leaf(pdata, $$, ';', @2); }
| RETURN expression ';' { $$ = make_node(pdata, "jump_statement.4"); node_add_leaf(pdata, $$, 'RETURN', @1); node_add_child(pdata, $$, $2); node_add_leaf(pdata, $$, ';', @3); }
;
translation_unit
: external_declaration { $$ = make_node(pdata, "translation_unit.0"); node_add_child(pdata, $$, $1); }
| translation_unit external_declaration { $$ = $1; node_add_child(pdata, $$, $2); }
;
external_declaration
: function_definition { $$ = make_node(pdata, "external_declaration.0"); node_add_child(pdata, $$, $1); }
| declaration { $$ = make_node(pdata, "external_declaration.1"); node_add_child(pdata, $$, $1); }
;
function_definition
: declaration_specifiers declarator declaration_list compound_statement { $$ = make_node(pdata, "function_definition.0"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); node_add_child(pdata, $$, $4); }
| declaration_specifiers declarator compound_statement { $$ = make_node(pdata, "function_definition.1"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); }
| declarator declaration_list compound_statement { $$ = make_node(pdata, "function_definition.2"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); node_add_child(pdata, $$, $3); }
| declarator compound_statement { $$ = make_node(pdata, "function_definition.3"); node_add_child(pdata, $$, $1); node_add_child(pdata, $$, $2); }
;