%{ #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 CHAR_CONST; %token INT_CONST; %token FLOAT_CONST; %token STRING_LITERAL; %token IDENTIFIER; %token TYPE_NAME; %start translation_unit %% constant : INT_CONST | FLOAT_CONST | CHAR_CONST ; primary_expression : IDENTIFIER | constant | STRING_LITERAL | LPAREN expression RPAREN ; 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 ; argument_expression_list : assignment_expression | argument_expression_list COMMA assignment_expression ; unary_expression : postfix_expression | INCREMENT unary_expression | DECREMENT unary_expression | unary_operator cast_expression | SIZEOF unary_expression | SIZEOF LPAREN type_name RPAREN ; unary_operator : BITAND | TIMES | PLUS | MINUS | BITNOT | NOT ; cast_expression : unary_expression | LPAREN type_name RPAREN cast_expression ; multiplicative_expression : cast_expression | multiplicative_expression TIMES cast_expression | multiplicative_expression DIVIDE cast_expression | multiplicative_expression MOD cast_expression ; additive_expression : multiplicative_expression | additive_expression PLUS multiplicative_expression | additive_expression MINUS multiplicative_expression ; shift_expression : additive_expression | shift_expression LSHIFT additive_expression | shift_expression RSHIFT additive_expression ; relational_expression : shift_expression | relational_expression LESS shift_expression | relational_expression GREATER shift_expression | relational_expression LESSEQ shift_expression | relational_expression GREATEREQ shift_expression ; equality_expression : relational_expression | equality_expression EQUALS relational_expression | equality_expression NOTEQUALS relational_expression ; and_expression : equality_expression | and_expression BITAND equality_expression ; exclusive_or_expression : and_expression | exclusive_or_expression XOR and_expression ; inclusive_or_expression : exclusive_or_expression | inclusive_or_expression BITOR exclusive_or_expression ; logical_and_expression : inclusive_or_expression | logical_and_expression AND inclusive_or_expression ; logical_or_expression : logical_and_expression | logical_or_expression OR logical_and_expression ; conditional_expression : logical_or_expression | logical_or_expression QUESTION expression COLON conditional_expression ; assignment_expression : conditional_expression | unary_expression assignment_operator assignment_expression ; assignment_operator : ASSIGN | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN | OR_ASSIGN ; expression : assignment_expression | expression COMMA assignment_expression ; constant_expression : conditional_expression ; declaration : declaration_specifiers SEMICOLON | declaration_specifiers init_declarator_list SEMICOLON { 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->declarator.name); } break; } } } ; declaration_specifiers : storage_class_specifier { $$ = new Node(NODE_TYPE_LIST); $$->list->push_back($1); } | storage_class_specifier declaration_specifiers { $$ = $2; $$->list->push_back($1); } | type_specifier { $$ = new Node(NODE_TYPE_LIST); $$->list->push_back($1); } | type_specifier declaration_specifiers { $$ = $2; $$->list->push_back($1); } | type_qualifier { $$ = new Node(NODE_TYPE_LIST); $$->list->push_back($1); } | type_qualifier declaration_specifiers { $$ = $2; $$->list->push_back($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($3); } ; init_declarator : declarator | declarator ASSIGN initializer ; storage_class_specifier : TYPEDEF | EXTERN | STATIC | AUTO | REGISTER ; type_specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | struct_or_union_specifier | enum_specifier | TYPE_NAME ; struct_or_union_specifier : struct_or_union IDENTIFIER LCURLY struct_declaration_list RCURLY | struct_or_union LCURLY struct_declaration_list RCURLY | struct_or_union IDENTIFIER ; struct_or_union : STRUCT | UNION ; struct_declaration_list : struct_declaration | struct_declaration_list struct_declaration ; struct_declaration : specifier_qualifier_list struct_declarator_list SEMICOLON ; specifier_qualifier_list : type_specifier specifier_qualifier_list | type_specifier | type_qualifier specifier_qualifier_list | type_qualifier ; struct_declarator_list : struct_declarator | struct_declarator_list COMMA struct_declarator ; struct_declarator : declarator | COLON constant_expression | declarator COLON constant_expression ; enum_specifier : ENUM LCURLY enumerator_list RCURLY | ENUM IDENTIFIER LCURLY enumerator_list RCURLY | ENUM IDENTIFIER ; enumerator_list : enumerator | enumerator_list COMMA enumerator ; enumerator : IDENTIFIER | IDENTIFIER ASSIGN constant_expression ; type_qualifier : CONST | VOLATILE ; declarator : pointer direct_declarator { $$ = $2; } | direct_declarator ; direct_declarator : IDENTIFIER { $$ = new Node(NODE_TYPE_DECLARATOR); $$->declarator.name = $1->token.text; } | 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 ; type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ; parameter_type_list : parameter_list | parameter_list COMMA ELLIPSIS ; parameter_list : parameter_declaration | parameter_list COMMA parameter_declaration ; parameter_declaration : declaration_specifiers declarator | declaration_specifiers abstract_declarator | declaration_specifiers ; identifier_list : IDENTIFIER | identifier_list COMMA IDENTIFIER ; type_name : specifier_qualifier_list | specifier_qualifier_list abstract_declarator ; abstract_declarator : pointer | direct_abstract_declarator | pointer direct_abstract_declarator ; 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 ; initializer : assignment_expression | LCURLY initializer_list RCURLY | LCURLY initializer_list COMMA RCURLY ; initializer_list : initializer | initializer_list COMMA initializer ; statement : labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement ; labeled_statement : IDENTIFIER COLON statement | CASE constant_expression COLON statement | DEFAULT COLON statement ; compound_statement : LCURLY RCURLY | LCURLY statement_list RCURLY | LCURLY declaration_list RCURLY | LCURLY declaration_list statement_list RCURLY ; declaration_list : declaration | declaration_list declaration ; statement_list : statement | statement_list statement ; expression_statement : SEMICOLON | expression SEMICOLON ; selection_statement : IF LPAREN expression RPAREN statement | IF LPAREN expression RPAREN statement ELSE statement | SWITCH LPAREN expression RPAREN statement ; 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 ; jump_statement : GOTO IDENTIFIER SEMICOLON | CONTINUE SEMICOLON | BREAK SEMICOLON | RETURN SEMICOLON | RETURN expression SEMICOLON ; translation_unit : external_declaration | translation_unit external_declaration ; external_declaration : function_definition | declaration ; function_definition : declaration_specifiers declarator declaration_list compound_statement | declaration_specifiers declarator compound_statement | declarator declaration_list compound_statement | declarator compound_statement ; %%