568 lines
11 KiB
Plaintext
568 lines
11 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 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
|
|
;
|
|
|
|
%%
|