%{ #include #include "parser.h" #include #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); } ; %%