diff --git a/src/Node.cc b/src/Node.cc index a43a997..da49315 100644 --- a/src/Node.cc +++ b/src/Node.cc @@ -10,4 +10,5 @@ Node::Node(int _type) list = new std::vector(); break; } + declarator_name = nullptr; } diff --git a/src/Node.h b/src/Node.h index bc29918..c95b5a4 100644 --- a/src/Node.h +++ b/src/Node.h @@ -19,18 +19,15 @@ public: std::string * text; } token; std::vector * list; - struct - { - std::string * name; - } declarator; }; + std::string * declarator_name; }; enum { + NODE_TYPE_NULL, NODE_TYPE_TOKEN, NODE_TYPE_LIST, - NODE_TYPE_DECLARATOR, }; #endif diff --git a/src/parser/parser.cc b/src/parser/parser.cc index 4dd6b7f..8ea59c9 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -195,9 +195,33 @@ void handle_parse_error(const char * str, const YYLTYPE * yylloc) display_error_source(yylloc->last_line, yylloc->last_column); } -void observe_type_name(const std::string & type_name) +const std::string * find_declarator_name(const Node * node) { - type_names.insert(type_name); + if (node->declarator_name != nullptr) + { + return node->declarator_name; + } + if (node->type == NODE_TYPE_LIST) + { + for (auto n : *node->list) + { + const std::string * s = find_declarator_name(n); + if (s != nullptr) + { + return s; + } + } + } + return nullptr; +} + +void observe_type_name(const Node * node) +{ + const std::string * declarator_name = find_declarator_name(node); + if (declarator_name != nullptr) + { + type_names.insert(*declarator_name); + } } static const char * builtin_types[] = { diff --git a/src/parser/parser.h b/src/parser/parser.h index aff5e90..cf4f205 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -12,7 +12,7 @@ extern std::unordered_set type_names; void parse(const char * filename); void handle_parse_error(const char * str, const YYLTYPE * yylloc); -void observe_type_name(const std::string & type_name); +void observe_type_name(const Node * node); bool is_type_name(const std::string & type_name); #endif diff --git a/src/parser/parser.yc b/src/parser/parser.yc index c3503b3..b07d0aa 100644 --- a/src/parser/parser.yc +++ b/src/parser/parser.yc @@ -122,161 +122,382 @@ int yylex(YYSTYPE *, YYLTYPE *); %% constant - : INT_CONST - | FLOAT_CONST - | CHAR_CONST + : INT_CONST { $$ = $1; } + | FLOAT_CONST { $$ = $1; } + | CHAR_CONST { $$ = $1; } ; primary_expression - : IDENTIFIER - | constant - | string_literals - | LPAREN expression RPAREN + : 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 - | string_literals STRING_LITERAL + : STRING_LITERAL { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + } + | string_literals STRING_LITERAL { + $$ = $1; + $$->list->push_back($2); + } ; 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 + : 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 - | argument_expression_list COMMA assignment_expression + : 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 - | INCREMENT unary_expression - | DECREMENT unary_expression - | unary_operator cast_expression - | SIZEOF unary_expression - | SIZEOF LPAREN type_name RPAREN - | ALIGNOF unary_expression - | ALIGNOF LPAREN type_name RPAREN - | LCURLY initializer_list RCURLY - | LCURLY initializer_list COMMA RCURLY + : 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 - | TIMES - | PLUS - | MINUS - | BITNOT - | NOT + : BITAND { $$ = $1; } + | TIMES { $$ = $1; } + | PLUS { $$ = $1; } + | MINUS { $$ = $1; } + | BITNOT { $$ = $1; } + | NOT { $$ = $1; } ; cast_expression - : unary_expression - | LPAREN type_name RPAREN 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 - | multiplicative_expression TIMES cast_expression - | multiplicative_expression DIVIDE cast_expression - | multiplicative_expression MOD cast_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 - | additive_expression PLUS multiplicative_expression - | additive_expression MINUS multiplicative_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 - | shift_expression LSHIFT additive_expression - | shift_expression RSHIFT additive_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 - | relational_expression LESS shift_expression - | relational_expression GREATER shift_expression - | relational_expression LESSEQ shift_expression - | relational_expression GREATEREQ shift_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 - | equality_expression EQUALS relational_expression - | equality_expression NOTEQUALS relational_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 - | and_expression BITAND equality_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 - | exclusive_or_expression XOR and_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 - | inclusive_or_expression BITOR exclusive_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 - | logical_and_expression AND inclusive_or_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 - | logical_or_expression OR logical_and_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 - | logical_or_expression QUESTION expression COLON 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 - | unary_expression assignment_operator 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 - | MUL_ASSIGN - | DIV_ASSIGN - | MOD_ASSIGN - | ADD_ASSIGN - | SUB_ASSIGN - | LEFT_ASSIGN - | RIGHT_ASSIGN - | AND_ASSIGN - | XOR_ASSIGN - | OR_ASSIGN + : 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 - | EXTENSION assignment_expression - | expression COMMA assignment_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 + : conditional_expression { $$ = $1; } ; declaration - : declaration_specifiers SEMICOLON + : 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) && @@ -284,7 +505,7 @@ declaration { for (auto d : *$2->list) { - observe_type_name(*d->declarator.name); + observe_type_name(d); } break; } @@ -334,53 +555,76 @@ init_declarator_list } | init_declarator_list COMMA init_declarator { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; init_declarator - : declarator - | declarator ASSIGN initializer + : 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 - | EXTERN - | INLINE - | STATIC - | AUTO - | REGISTER + : TYPEDEF { $$ = $1; } + | EXTERN { $$ = $1; } + | INLINE { $$ = $1; } + | STATIC { $$ = $1; } + | AUTO { $$ = $1; } + | REGISTER { $$ = $1; } ; type_specifier - : VOID - | CHAR - | SHORT - | INT - | LONG - | FLOAT - | DOUBLE - | SIGNED - | UNSIGNED - | struct_or_union_specifier - | enum_specifier - | TYPE_NAME + : 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 - | struct_or_union LCURLY struct_declaration_list RCURLY - | struct_or_union identifier_or_type_name + : 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 - | TYPE_NAME + : IDENTIFIER { $$ = $1; } + | TYPE_NAME { $$ = $1; } ; struct_or_union - : STRUCT - | UNION + : STRUCT { $$ = $1; } + | UNION { $$ = $1; } ; struct_declaration_list @@ -395,8 +639,17 @@ struct_declaration_list ; struct_declaration - : specifier_qualifier_list SEMICOLON - | specifier_qualifier_list struct_declarator_list SEMICOLON + : 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 @@ -425,20 +678,46 @@ struct_declarator_list } | struct_declarator_list COMMA struct_declarator { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; struct_declarator - : declarator - | COLON constant_expression - | declarator COLON constant_expression + : 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 - | ENUM IDENTIFIER LCURLY enumerator_list RCURLY - | ENUM IDENTIFIER + : ENUM LCURLY enumerator_list RCURLY { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + $$->list->push_back($2); + $$->list->push_back($3); + } + | 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 @@ -448,45 +727,106 @@ enumerator_list } | enumerator_list COMMA enumerator { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; enumerator - : IDENTIFIER - | IDENTIFIER ASSIGN constant_expression + : 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 - | VOLATILE - | RESTRICT - | EXTENSION + : CONST { $$ = $1; } + | VOLATILE { $$ = $1; } + | RESTRICT { $$ = $1; } + | EXTENSION { $$ = $1; } ; declarator - : pointer direct_declarator attributes { $$ = $2; } - | direct_declarator attributes + : 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 { - $$ = new Node(NODE_TYPE_DECLARATOR); - $$->declarator.name = $1->token.text; + $$ = $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); } - | LPAREN declarator RPAREN { $$ = $2; } - | 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 - : TIMES - | TIMES type_qualifier_list - | TIMES pointer - | TIMES type_qualifier_list 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 @@ -495,14 +835,19 @@ type_qualifier_list $$->list->push_back($1); } | type_qualifier_list type_qualifier { - $$ = $2; - $$->list->push_back($1); + $$ = $1; + $$->list->push_back($2); } ; parameter_type_list - : parameter_list - | parameter_list COMMA ELLIPSIS + : 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 @@ -512,14 +857,23 @@ parameter_list } | parameter_list COMMA parameter_declaration { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; parameter_declaration - : declaration_specifiers declarator - | declaration_specifiers abstract_declarator - | declaration_specifiers + : 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 @@ -529,35 +883,89 @@ identifier_list } | identifier_list COMMA IDENTIFIER { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; type_name - : specifier_qualifier_list - | specifier_qualifier_list abstract_declarator + : 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 - | direct_abstract_declarator - | pointer direct_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 - | 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 + : 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 + : assignment_expression { $$ = $1; } ; initializer_list @@ -567,31 +975,68 @@ initializer_list } | initializer_list COMMA initializer { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; statement - : labeled_statement - | compound_statement - | expression_statement - | selection_statement - | iteration_statement - | jump_statement - | asm_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 - | CASE constant_expression COLON statement - | DEFAULT COLON 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 - | LCURLY statement_list RCURLY - | LCURLY declaration_list RCURLY - | LCURLY declaration_list statement_list RCURLY + : 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 @@ -617,82 +1062,239 @@ statement_list ; expression_statement - : SEMICOLON - | expression SEMICOLON + : SEMICOLON { $$ = $1; } + | expression SEMICOLON { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + $$->list->push_back($2); + } ; selection_statement - : IF LPAREN expression RPAREN statement - | IF LPAREN expression RPAREN statement ELSE statement - | SWITCH LPAREN expression RPAREN 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 - | DO statement WHILE LPAREN expression RPAREN SEMICOLON - | FOR LPAREN expression_statement expression_statement RPAREN statement - | FOR LPAREN expression_statement expression_statement expression RPAREN 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); + } ; jump_statement - : GOTO IDENTIFIER SEMICOLON - | CONTINUE SEMICOLON - | BREAK SEMICOLON - | RETURN SEMICOLON - | RETURN expression SEMICOLON + : 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 + : 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 - | ASM VOLATILE LPAREN string_literals asm_operands RPAREN + : 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 - : - | asm_operand - | asm_operands asm_operand + : { $$ = 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 + : COLON primary_expressions { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + $$->list->push_back($2); + } ; primary_expressions - : primary_expression - | primary_expressions primary_expression + : primary_expression { $$ = $1; } + | primary_expressions primary_expression { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + $$->list->push_back($2); + } ; translation_unit - : external_declaration - | translation_unit external_declaration + : external_declaration { $$ = $1; } + | translation_unit external_declaration { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + $$->list->push_back($2); + } ; external_declaration - : function_definition - | declaration + : function_definition { $$ = $1; } + | declaration { $$ = $1; } ; function_definition - : declaration_specifiers declarator declaration_list attributes compound_statement - | declaration_specifiers declarator attributes compound_statement - | declarator declaration_list attributes compound_statement - | declarator attributes compound_statement + : 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 - : { $$ = nullptr; } - | attribute_spec - | attributes attribute_spec - | asm_expression - | attributes asm_expression + : { $$ = 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 + : 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 @@ -702,13 +1304,20 @@ attribute_list } | attribute_list COMMA attribute { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ; attribute - : IDENTIFIER - | IDENTIFIER LPAREN expression_list RPAREN + : 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 @@ -718,6 +1327,7 @@ expression_list } | expression_list COMMA expression { $$ = $1; + $$->list->push_back($2); $$->list->push_back($3); } ;