forked from stardust95/TinyCompiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.y
170 lines (148 loc) · 7.73 KB
/
grammar.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
%{
#include "ASTNodes.h"
#include <stdio.h>
NBlock* programBlock;
extern int yylex();
void yyerror(const char* s)
{
printf("Error: %s\n", s);
}
%}
%union
{
NBlock* block;
NExpression* expr;
NStatement* stmt;
NIdentifier* ident;
NVariableDeclaration* var_decl;
NArrayIndex* index;
std::vector<shared_ptr<NVariableDeclaration>>* varvec;
std::vector<shared_ptr<NExpression>>* exprvec;
std::string* string;
int token;
}
%token <string> TIDENTIFIER TINTEGER TDOUBLE TYINT TYDOUBLE TYFLOAT TYCHAR TYBOOL TYVOID TYSTRING TEXTERN TLITERAL
%token <token> TCEQ TCNE TCLT TCLE TCGT TCGE TEQUAL
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TDOT TSEMICOLON TLBRACKET TRBRACKET TQUOTATION
%token <token> TPLUS TMINUS TMUL TDIV TAND TOR TXOR TMOD TNEG TNOT TSHIFTL TSHIFTR
%token <token> TIF TELSE TFOR TWHILE TRETURN TSTRUCT
%type <index> array_index
%type <ident> ident primary_typename array_typename struct_typename typename
%type <expr> numeric expr assign
%type <varvec> func_decl_args struct_members
%type <exprvec> call_args
%type <block> program stmts block
%type <stmt> stmt var_decl func_decl struct_decl if_stmt for_stmt while_stmt
%type <token> comparison
%left TPLUS TMINUS
%left TMUL TDIV TMOD
%start program
%%
program : stmts { programBlock = $1; }
;
stmts : stmt { $$ = new NBlock(); $$->statements->push_back(shared_ptr<NStatement>($1)); }
| stmts stmt { $1->statements->push_back(shared_ptr<NStatement>($2)); }
;
stmt : var_decl | func_decl | struct_decl
| expr { $$ = new NExpressionStatement(shared_ptr<NExpression>($1)); }
| TRETURN expr { $$ = new NReturnStatement(shared_ptr<NExpression>($2)); }
| if_stmt
| for_stmt
| while_stmt
;
block : TLBRACE stmts TRBRACE { $$ = $2; }
| TLBRACE TRBRACE { $$ = new NBlock(); }
;
primary_typename : TYINT { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYDOUBLE { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYFLOAT { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYCHAR { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYBOOL { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYVOID { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
| TYSTRING { $$ = new NIdentifier(*$1); $$->isType = true; delete $1; }
array_typename : primary_typename TLBRACKET TINTEGER TRBRACKET {
$1->isArray = true;
$1->arraySize->push_back(make_shared<NInteger>(atol($3->c_str())));
$$ = $1;
}
| array_typename TLBRACKET TINTEGER TRBRACKET {
$1->arraySize->push_back(make_shared<NInteger>(atol($3->c_str())));
$$ = $1;
}
struct_typename : TSTRUCT ident {
$2->isType = true;
$$ = $2;
}
typename : primary_typename { $$ = $1; }
| array_typename { $$ = $1; }
| struct_typename { $$ = $1; }
var_decl : typename ident { $$ = new NVariableDeclaration(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($2), nullptr); }
| typename ident TEQUAL expr { $$ = new NVariableDeclaration(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($2), shared_ptr<NExpression>($4)); }
| typename ident TEQUAL TLBRACKET call_args TRBRACKET {
$$ = new NArrayInitialization(make_shared<NVariableDeclaration>(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($2), nullptr), shared_ptr<ExpressionList>($5));
}
;
func_decl : typename ident TLPAREN func_decl_args TRPAREN block
{ $$ = new NFunctionDeclaration(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($2), shared_ptr<VariableList>($4), shared_ptr<NBlock>($6)); }
| TEXTERN typename ident TLPAREN func_decl_args TRPAREN { $$ = new NFunctionDeclaration(shared_ptr<NIdentifier>($2), shared_ptr<NIdentifier>($3), shared_ptr<VariableList>($5), nullptr, true); }
func_decl_args : /* blank */ { $$ = new VariableList(); }
| var_decl { $$ = new VariableList(); $$->push_back(shared_ptr<NVariableDeclaration>($<var_decl>1)); }
| func_decl_args TCOMMA var_decl { $1->push_back(shared_ptr<NVariableDeclaration>($<var_decl>3)); }
;
ident : TIDENTIFIER { $$ = new NIdentifier(*$1); delete $1; }
;
numeric : TINTEGER { $$ = new NInteger(atol($1->c_str())); }
| TDOUBLE { $$ = new NDouble(atof($1->c_str())); }
;
expr : assign { $$ = $1; }
| ident TLPAREN call_args TRPAREN { $$ = new NMethodCall(shared_ptr<NIdentifier>($1), shared_ptr<ExpressionList>($3)); }
| ident { $<ident>$ = $1; }
| ident TDOT ident { $$ = new NStructMember(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($3)); }
| numeric
| expr comparison expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| expr TMOD expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| expr TMUL expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| expr TDIV expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| expr TPLUS expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| expr TMINUS expr { $$ = new NBinaryOperator(shared_ptr<NExpression>($1), $2, shared_ptr<NExpression>($3)); }
| TLPAREN expr TRPAREN { $$ = $2; }
| TMINUS expr { $$ = nullptr; /* TODO */ }
| array_index { $$ = $1; }
| TLITERAL { $$ = new NLiteral(*$1); delete $1; }
;
array_index : ident TLBRACKET expr TRBRACKET
{ $$ = new NArrayIndex(shared_ptr<NIdentifier>($1), shared_ptr<NExpression>($3)); }
| array_index TLBRACKET expr TRBRACKET
{
$1->expressions->push_back(shared_ptr<NExpression>($3));
$$ = $1;
}
assign : ident TEQUAL expr { $$ = new NAssignment(shared_ptr<NIdentifier>($1), shared_ptr<NExpression>($3)); }
| array_index TEQUAL expr {
$$ = new NArrayAssignment(shared_ptr<NArrayIndex>($1), shared_ptr<NExpression>($3));
}
| ident TDOT ident TEQUAL expr {
auto member = make_shared<NStructMember>(shared_ptr<NIdentifier>($1), shared_ptr<NIdentifier>($3));
$$ = new NStructAssignment(member, shared_ptr<NExpression>($5));
}
;
call_args : /* blank */ { $$ = new ExpressionList(); }
| expr { $$ = new ExpressionList(); $$->push_back(shared_ptr<NExpression>($1)); }
| call_args TCOMMA expr { $1->push_back(shared_ptr<NExpression>($3)); }
comparison : TCEQ | TCNE | TCLT | TCLE | TCGT | TCGE
| TAND | TOR | TXOR | TSHIFTL | TSHIFTR
;
if_stmt : TIF expr block { $$ = new NIfStatement(shared_ptr<NExpression>($2), shared_ptr<NBlock>($3)); }
| TIF expr block TELSE block { $$ = new NIfStatement(shared_ptr<NExpression>($2), shared_ptr<NBlock>($3), shared_ptr<NBlock>($5)); }
| TIF expr block TELSE if_stmt {
auto blk = new NBlock();
blk->statements->push_back(shared_ptr<NStatement>($5));
$$ = new NIfStatement(shared_ptr<NExpression>($2), shared_ptr<NBlock>($3), shared_ptr<NBlock>(blk));
}
for_stmt : TFOR TLPAREN expr TSEMICOLON expr TSEMICOLON expr TRPAREN block { $$ = new NForStatement(shared_ptr<NBlock>($9), shared_ptr<NExpression>($3), shared_ptr<NExpression>($5), shared_ptr<NExpression>($7)); }
while_stmt : TWHILE TLPAREN expr TRPAREN block { $$ = new NForStatement(shared_ptr<NBlock>($5), nullptr, shared_ptr<NExpression>($3), nullptr); }
struct_decl : TSTRUCT ident TLBRACE struct_members TRBRACE {$$ = new NStructDeclaration(shared_ptr<NIdentifier>($2), shared_ptr<VariableList>($4)); }
struct_members : /* blank */ { $$ = new VariableList(); }
| var_decl { $$ = new VariableList(); $$->push_back(shared_ptr<NVariableDeclaration>($<var_decl>1)); }
| struct_members var_decl { $1->push_back(shared_ptr<NVariableDeclaration>($<var_decl>2)); }
%%