-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.y
More file actions
177 lines (151 loc) · 5.46 KB
/
parser.y
File metadata and controls
177 lines (151 loc) · 5.46 KB
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
171
172
173
174
175
176
177
%{
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iostream>
#include"node.h"
Block *programBlock;
extern int yylex();
void yyerror(const char *s) { printf("ERROR: %s\n", s); }
long long changeToInt(const char* str);
double changeToDouble(const char* str);
%}
%union{
Node* node;
Block *block;
Statement *stmt;
Expression *expr;
Identifier *ident;
ArrayIndex *index;
VariableList *varvec;
ExpressionList *exprvec;
VariableDecration *var_decl;
std::string *str;
int token;
};
%token<str> Int Float Double Long Short Signed Char Unsigned Auto Bool
%token<token> Break Case Const Else For If Return While
%token<str> INT DOUBLE ID
%token<token> EQ GT LT EQEQ GE LE NE
%token<token> LPAREN RPAREN LBRACE RBRACE LMBRA RMBRA
%token<token> ADD SUB MUL DIV
%token<token> SEMI DOT COMMA
%type<index> array_index
%type<ident> mytype primary_type array_type
%type<ident> ident
%type<expr> number expr assign
%type<varvec> func_argv
%type<exprvec> call_argv
%type<block> program stmts block
%type<stmt> stmt var_decl func_decl if_stmt for_stmt while_stmt
%type<token> comprison
%left ADD SUB
%left MUL DIV
%start program
%%
program: stmts { programBlock = $1; }
;
stmts:
stmt { $$ = new Block(); $$->statements.push_back($1); }
|
stmts stmt { $1->statements.push_back($2); }
;
stmt:
var_decl | func_decl
| expr { $$ = new ExpressionStatement(*$1); }
| Return expr { $$ = new ReturnStatement(*$2); }
| if_stmt { printf("if_stmt created\n"); }
| for_stmt { printf("for_stmt created\n"); }
| while_stmt { printf("while_stmt created\n"); }
;
var_decl:
mytype ident {$$ = new VariableDecration(shared_ptr<Identifier>($1),*$2); }
| mytype ident EQ expr {$$ = new VariableDecration(shared_ptr<Identifier>($1),*$2,$4); }
| mytype ident EQ LMBRA call_argv RMBRA { auto varial = new VariableDecration(shared_ptr<Identifier>($1),*$2); $$ = new ArrayInitialization(*varial,*$5);}
;
func_decl:
mytype ident LPAREN func_argv RPAREN block { $$ = new FuncStatement(*$1,*$2,*$4,*$6); }
;
block:
LBRACE RBRACE { $$ = new Block(); }
| LBRACE stmts RBRACE { $$ = $2; }
;
func_argv: { $$ = new VariableList(); }
| var_decl { $$ = new VariableList(); $$->push_back($<var_decl>1); }
| func_argv COMMA var_decl { $1->push_back($<var_decl>3); }
;
assign:
ident EQ expr { $$ = new AssignExpression(*$1,*$3); }
|
array_index EQ expr { $$ = new ArrayAssignment(shared_ptr<ArrayIndex>($1),*$3);}
;
expr:
assign { $$ = $1; }
| ident LPAREN call_argv RPAREN { $$ = new CallExpression(*$1,*$3);}
| ident { $$ = $1;}
| number
| expr MUL expr { $$ = new BinaryExpression(shared_ptr<Expression>($1),$2,shared_ptr<Expression>($3)); }
| expr DIV expr { $$ = new BinaryExpression(shared_ptr<Expression>($1),$2,shared_ptr<Expression>($3)); }
| expr ADD expr { $$ = new BinaryExpression(shared_ptr<Expression>($1),$2,shared_ptr<Expression>($3)); }
| expr SUB expr { $$ = new BinaryExpression(shared_ptr<Expression>($1),$2,shared_ptr<Expression>($3)); }
| expr comprison expr { $$ = new BinaryExpression(shared_ptr<Expression>($1),$2,shared_ptr<Expression>($3));}
| LPAREN expr RPAREN { $$ = $2;}
| array_index { $$ = $1;}
;
call_argv:{ $$ = new ExpressionList; }
| expr { $$ = new ExpressionList; $$->push_back($1); }
| call_argv COMMA expr { $1->push_back($3); }
;
comprison:
GT | LT | EQEQ | GE | LE | NE
;
ident:
ID { $$ = new Identifier(*$1); }
;
array_index:
ident LMBRA expr RMBRA { $$ = new ArrayIndex(*$1,shared_ptr<Expression>($3)); }
;
number:
INT { long long a = std::stoll(*$1); $$ = new IntExpression(a); }
| DOUBLE {double a = changeToDouble($1->c_str()); $$ = new DoubleExpression(a); }
;
primary_type:
Int { $$ = new Identifier(*$1); $$->isType = true; }
| Float { $$ = new Identifier(*$1); $$->isType = true; }
| Double { $$ = new Identifier(*$1); $$->isType = true; }
| Long { $$ = new Identifier(*$1); $$->isType = true; }
| Short { $$ = new Identifier(*$1); $$->isType = true; }
| Signed { $$ = new Identifier(*$1); $$->isType = true; }
| Char { $$ = new Identifier(*$1); $$->isType = true; }
| Unsigned { $$ = new Identifier(*$1); $$->isType = true; }
| Auto { $$ = new Identifier(*$1); $$->isType = true; }
| Bool { $$ = new Identifier(*$1); $$->isType = true; }
;
array_type:
primary_type LMBRA INT RMBRA {long long a = std::stoll(*$3); $1->isArray = true; $1->arraySize->push_back(make_shared<IntExpression>(a)); $$ = $1;}
;
mytype:
primary_type { $$ = $1;}
| array_type { $$ = $1;}
;
if_stmt:
If expr block { $$ = new IfStatement(shared_ptr<Expression>($2),shared_ptr<Block>($3)); }
| If expr block Else block { $$ = new IfStatement(shared_ptr<Expression>($2),shared_ptr<Block>($3),shared_ptr<Block>($5)); }
| If expr block Else if_stmt { auto blk = new Block(); blk->statements.push_back($5);
$$ = new IfStatement(shared_ptr<Expression>($2),shared_ptr<Block>(blk)); }
;
for_stmt:
For LPAREN expr SEMI expr SEMI expr RPAREN block { $$ = new ForStatement(shared_ptr<Block>($9),shared_ptr<Expression>($3),shared_ptr<Expression>($5),shared_ptr<Expression>($7)); }
;
while_stmt:
While LPAREN expr RPAREN block { $$ = new ForStatement(shared_ptr<Block>($5),nullptr,shared_ptr<Expression>($3),nullptr); }
;
%%
long long changeToInt(const char* str){
long long sum = atol(str);
return sum;
}
double changeToDouble(const char* str){
double sum = atof(str);
return sum;
}