cxl/src/parser/parser.yc

1360 lines
34 KiB
Plaintext

%{
#include <stdio.h>
#include "parser.h"
#include <iostream>
#define yyerror(msg) handle_parse_error(msg, &yylloc)
int yylex(YYSTYPE *, YYLTYPE *);
%}
%pure-parser
%locations
%error-verbose
%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 SEMICOLON;
%token COLON;
%token QUESTION;
%token DOT;
%token ARROW;
%token COMMA;
%token ELLIPSIS;
%token LCURLY;
%token RCURLY;
%token LBRACKET;
%token RBRACKET;
%token LPAREN;
%token RPAREN;
%token VOID;
%token CHAR;
%token SHORT;
%token INT;
%token LONG;
%token FLOAT;
%token DOUBLE;
%token SIGNED;
%token UNSIGNED;
%token VOLATILE;
%token STATIC;
%token CONST;
%token EXTERN;
%token AUTO;
%token REGISTER;
%token INLINE;
%token STRUCT;
%token UNION;
%token ENUM;
%token TYPEDEF;
%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 SIZEOF;
%token ALIGNOF;
%token CHAR_CONST;
%token INT_CONST;
%token FLOAT_CONST;
%token STRING_LITERAL;
%token IDENTIFIER;
%token TYPE_NAME;
%token ATTRIBUTE;
%token RESTRICT;
%token ASM;
%token EXTENSION;
%start translation_unit
%%
constant
: INT_CONST { $$ = $1; }
| FLOAT_CONST { $$ = $1; }
| CHAR_CONST { $$ = $1; }
;
primary_expression
: IDENTIFIER { $$ = $1; }
| constant { $$ = $1; }
| string_literals { $$ = $1; }
| LPAREN expression RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
string_literals
: STRING_LITERAL {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| string_literals STRING_LITERAL {
$$ = $1;
$$->list->push_back($2);
}
;
postfix_expression
: primary_expression { $$ = $1; }
| postfix_expression LBRACKET expression RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| postfix_expression LPAREN RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| postfix_expression LPAREN argument_expression_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| postfix_expression DOT IDENTIFIER {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| postfix_expression ARROW IDENTIFIER {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| postfix_expression INCREMENT {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| postfix_expression DECREMENT {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
argument_expression_list
: assignment_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| argument_expression_list COMMA assignment_expression {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
unary_expression
: postfix_expression { $$ = $1; }
| INCREMENT unary_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| DECREMENT unary_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| unary_operator cast_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| SIZEOF unary_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| SIZEOF LPAREN type_name RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| ALIGNOF unary_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| ALIGNOF LPAREN type_name RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| LCURLY initializer_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| LCURLY initializer_list COMMA RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
;
unary_operator
: BITAND { $$ = $1; }
| TIMES { $$ = $1; }
| PLUS { $$ = $1; }
| MINUS { $$ = $1; }
| BITNOT { $$ = $1; }
| NOT { $$ = $1; }
;
cast_expression
: unary_expression { $$ = $1; }
| LPAREN type_name RPAREN cast_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
;
multiplicative_expression
: cast_expression { $$ = $1; }
| multiplicative_expression TIMES cast_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| multiplicative_expression DIVIDE cast_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| multiplicative_expression MOD cast_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
additive_expression
: multiplicative_expression { $$ = $1; }
| additive_expression PLUS multiplicative_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| additive_expression MINUS multiplicative_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
shift_expression
: additive_expression { $$ = $1; }
| shift_expression LSHIFT additive_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| shift_expression RSHIFT additive_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
relational_expression
: shift_expression { $$ = $1; }
| relational_expression LESS shift_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| relational_expression GREATER shift_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| relational_expression LESSEQ shift_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| relational_expression GREATEREQ shift_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
equality_expression
: relational_expression { $$ = $1; }
| equality_expression EQUALS relational_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| equality_expression NOTEQUALS relational_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
and_expression
: equality_expression { $$ = $1; }
| and_expression BITAND equality_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
exclusive_or_expression
: and_expression { $$ = $1; }
| exclusive_or_expression XOR and_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
inclusive_or_expression
: exclusive_or_expression { $$ = $1; }
| inclusive_or_expression BITOR exclusive_or_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
logical_and_expression
: inclusive_or_expression { $$ = $1; }
| logical_and_expression AND inclusive_or_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
logical_or_expression
: logical_and_expression { $$ = $1; }
| logical_or_expression OR logical_and_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
conditional_expression
: logical_or_expression { $$ = $1; }
| logical_or_expression QUESTION expression COLON conditional_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
;
assignment_expression
: conditional_expression { $$ = $1; }
| unary_expression assignment_operator assignment_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
assignment_operator
: ASSIGN { $$ = $1; }
| MUL_ASSIGN { $$ = $1; }
| DIV_ASSIGN { $$ = $1; }
| MOD_ASSIGN { $$ = $1; }
| ADD_ASSIGN { $$ = $1; }
| SUB_ASSIGN { $$ = $1; }
| LEFT_ASSIGN { $$ = $1; }
| RIGHT_ASSIGN { $$ = $1; }
| AND_ASSIGN { $$ = $1; }
| XOR_ASSIGN { $$ = $1; }
| OR_ASSIGN { $$ = $1; }
;
expression
: assignment_expression { $$ = $1; }
| EXTENSION assignment_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| expression COMMA assignment_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
constant_expression
: conditional_expression { $$ = $1; }
;
declaration
: declaration_specifiers SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| declaration_specifiers init_declarator_list SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
for (auto d_s : *$1->list)
{
if ((d_s->type == NODE_TYPE_TOKEN) &&
(*d_s->token.text == "typedef"))
{
for (auto d : *$2->list)
{
observe_type_name(d);
}
break;
}
}
}
;
declaration_specifiers
: storage_class_specifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| storage_class_specifier declaration_specifiers {
$$ = $2;
$$->list->push_front($1);
}
| type_specifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| type_specifier declaration_specifiers {
$$ = $2;
$$->list->push_front($1);
}
| type_qualifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| type_qualifier declaration_specifiers {
$$ = $2;
$$->list->push_front($1);
}
| attribute_spec {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| attribute_spec declaration_specifiers {
$$ = $2;
$$->list->push_front($1);
}
;
init_declarator_list
: init_declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| init_declarator_list COMMA init_declarator {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
init_declarator
: declarator { $$ = $1; }
| declarator ASSIGN initializer {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
storage_class_specifier
: TYPEDEF { $$ = $1; }
| EXTERN { $$ = $1; }
| INLINE { $$ = $1; }
| STATIC { $$ = $1; }
| AUTO { $$ = $1; }
| REGISTER { $$ = $1; }
;
type_specifier
: VOID { $$ = $1; }
| CHAR { $$ = $1; }
| SHORT { $$ = $1; }
| INT { $$ = $1; }
| LONG { $$ = $1; }
| FLOAT { $$ = $1; }
| DOUBLE { $$ = $1; }
| SIGNED { $$ = $1; }
| UNSIGNED { $$ = $1; }
| struct_or_union_specifier { $$ = $1; }
| enum_specifier { $$ = $1; }
| TYPE_NAME { $$ = $1; }
;
struct_or_union_specifier
: struct_or_union identifier_or_type_name LCURLY struct_declaration_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| struct_or_union LCURLY struct_declaration_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| struct_or_union identifier_or_type_name {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
identifier_or_type_name
: IDENTIFIER { $$ = $1; }
| TYPE_NAME { $$ = $1; }
;
struct_or_union
: STRUCT { $$ = $1; }
| UNION { $$ = $1; }
;
struct_declaration_list
: struct_declaration {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| struct_declaration_list struct_declaration {
$$ = $1;
$$->list->push_back($2);
}
;
struct_declaration
: specifier_qualifier_list SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| specifier_qualifier_list struct_declarator_list SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
specifier_qualifier_list
: type_specifier specifier_qualifier_list {
$$ = $2;
$$->list->push_front($1);
}
| type_specifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| type_qualifier specifier_qualifier_list {
$$ = $2;
$$->list->push_front($1);
}
| type_qualifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
;
struct_declarator_list
: struct_declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
struct_declarator
: declarator { $$ = $1; }
| COLON constant_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| declarator COLON constant_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
enum_specifier
: ENUM LCURLY enumerator_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| ENUM IDENTIFIER LCURLY enumerator_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| ENUM IDENTIFIER {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
enumerator_list
: enumerator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| enumerator_list COMMA enumerator {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
enumerator
: IDENTIFIER { $$ = $1; }
| IDENTIFIER ASSIGN constant_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
type_qualifier
: CONST { $$ = $1; }
| VOLATILE { $$ = $1; }
| RESTRICT { $$ = $1; }
| EXTENSION { $$ = $1; }
;
declarator
: pointer direct_declarator attributes {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_declarator attributes {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
direct_declarator
: IDENTIFIER {
$$ = $1;
$$->declarator_name = $1->token.text;
}
| LPAREN declarator RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_declarator LBRACKET constant_expression RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| direct_declarator LBRACKET RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_declarator LPAREN parameter_type_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| direct_declarator LPAREN identifier_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| direct_declarator LPAREN RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
pointer
: TIMES { $$ = $1; }
| TIMES type_qualifier_list {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| TIMES pointer {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| TIMES type_qualifier_list pointer {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
type_qualifier_list
: type_qualifier {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| type_qualifier_list type_qualifier {
$$ = $1;
$$->list->push_back($2);
}
;
parameter_type_list
: parameter_list { $$ = $1; }
| parameter_list COMMA ELLIPSIS {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
parameter_list
: parameter_declaration {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| parameter_list COMMA parameter_declaration {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
parameter_declaration
: declaration_specifiers declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| declaration_specifiers abstract_declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| declaration_specifiers { $$ = $1; }
;
identifier_list
: IDENTIFIER {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| identifier_list COMMA IDENTIFIER {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
type_name
: specifier_qualifier_list { $$ = $1; }
| specifier_qualifier_list abstract_declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
abstract_declarator
: pointer { $$ = $1; }
| direct_abstract_declarator { $$ = $1; }
| pointer direct_abstract_declarator {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
direct_abstract_declarator
: LPAREN abstract_declarator RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| LBRACKET RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| LBRACKET constant_expression RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_abstract_declarator LBRACKET RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_abstract_declarator LBRACKET constant_expression RBRACKET {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| LPAREN RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| LPAREN parameter_type_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_abstract_declarator LPAREN RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| direct_abstract_declarator LPAREN parameter_type_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
;
initializer
: assignment_expression { $$ = $1; }
;
initializer_list
: initializer {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| initializer_list COMMA initializer {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
statement
: labeled_statement { $$ = $1; }
| compound_statement { $$ = $1; }
| expression_statement { $$ = $1; }
| selection_statement { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
| asm_statement { $$ = $1; }
;
labeled_statement
: IDENTIFIER COLON statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| CASE constant_expression COLON statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| DEFAULT COLON statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
compound_statement
: LCURLY RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| LCURLY statement_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| LCURLY declaration_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| LCURLY declaration_list statement_list RCURLY {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
;
declaration_list
: declaration {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| declaration_list declaration {
$$ = $1;
$$->list->push_back($2);
}
;
statement_list
: statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| statement_list statement {
$$ = $1;
$$->list->push_back($2);
}
;
expression_statement
: SEMICOLON { $$ = $1; }
| expression SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
selection_statement
: IF LPAREN expression RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| IF LPAREN expression RPAREN statement ELSE statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
$$->list->push_back($7);
}
| SWITCH LPAREN expression RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
;
iteration_statement
: WHILE LPAREN expression RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| DO statement WHILE LPAREN expression RPAREN SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
$$->list->push_back($7);
}
| FOR LPAREN expression_statement expression_statement RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
}
| FOR LPAREN expression_statement expression_statement expression RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
$$->list->push_back($7);
}
| FOR LPAREN declaration expression_statement RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
}
| FOR LPAREN declaration expression_statement expression RPAREN statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
$$->list->push_back($7);
}
;
jump_statement
: GOTO IDENTIFIER SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
| CONTINUE SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| BREAK SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| RETURN SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| RETURN expression SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
asm_statement
: asm_expression SEMICOLON {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
asm_expression
: ASM LPAREN string_literals asm_operands RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| ASM VOLATILE LPAREN string_literals asm_operands RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
}
;
asm_operands
: { $$ = new Node(NODE_TYPE_NULL); }
| asm_operand { $$ = $1; }
| asm_operands asm_operand {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
asm_operand
: COLON primary_expressions {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
primary_expressions
: primary_expression { $$ = $1; }
| primary_expressions primary_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
translation_unit
: external_declaration {
$$ = $1;
set_translation_unit_node($$);
}
| translation_unit external_declaration {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
set_translation_unit_node($$);
}
;
external_declaration
: function_definition { $$ = $1; }
| declaration { $$ = $1; }
;
function_definition
: declaration_specifiers declarator declaration_list attributes compound_statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
}
| declaration_specifiers declarator attributes compound_statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| declarator declaration_list attributes compound_statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
| declarator attributes compound_statement {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
}
;
attributes
: { $$ = new Node(NODE_TYPE_NULL); }
| attribute_spec { $$ = $1; }
| attributes attribute_spec {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
| asm_expression { $$ = $1; }
| attributes asm_expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
}
;
attribute_spec
: ATTRIBUTE LPAREN LPAREN attribute_list RPAREN RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
$$->list->push_back($5);
$$->list->push_back($6);
}
;
attribute_list
: attribute {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| attribute_list COMMA attribute {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
attribute
: IDENTIFIER { $$ = $1; }
| IDENTIFIER LPAREN expression_list RPAREN {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
$$->list->push_back($2);
$$->list->push_back($3);
$$->list->push_back($4);
}
;
expression_list
: expression {
$$ = new Node(NODE_TYPE_LIST);
$$->list->push_back($1);
}
| expression_list COMMA expression {
$$ = $1;
$$->list->push_back($2);
$$->list->push_back($3);
}
;
%%