-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpr.y
More file actions
365 lines (314 loc) · 9.95 KB
/
Copy pathexpr.y
File metadata and controls
365 lines (314 loc) · 9.95 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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
%language "c++"
%define parse.error verbose
%define api.value.type variant
%define api.parser.class {Parser}
%define api.namespace {Expr}
%parse-param{list &expr_list}
%parse-param{list &sub_list}
%code requires{
#include <string>
#include <unordered_map>
#include <vector>
#include "ast.h"
}
%{
#include <stdexcept>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include "tokens.h"
#include "ast.h"
Expr::Parser::token_type yylex(Expr::Parser::semantic_type *yylval);
extern int yylineno;
namespace Expr{
void Parser::error(const std::string& msg){
std::cout << "Error en linea: " << yylineno << std::endl;
throw std::runtime_error(msg);
}
}
%}
/* Declaracion de Tokens */
%token EOL
%token KwEntero
%token KwReal
%token KwCadena
%token KwBooleano
%token KwCaracter
%token KwArreglo
%token KwDe
%token KwFuncion "funcion"
%token KwProcedimiento
%token KwVar
%token KwInicio "inicio"
%token KwFin
%token KwFinal
%token KwSi
%token KwEntonces
%token KwSino
%token KwPara
%token KwMientras
%token KwHaga
%token KwLlamar
%token KwRepita
%token KwHasta
%token KwCaso
%token OpOr
%token OpAnd
%token OpNot
%token OpDiv
%token OpMod
%token KwLea
%token KwEscriba
%token KwRetorne
%token KwTipo
%token KwEs
%token KwRegistro
%token KwArchivo
%token KwSecuencial
%token KwAbrir
%token KwComo
%token KwLectura
%token KwEscritura
%token KwCerrar
%token KwLeer
%token KwEscribir
%token OpTrue
%token OpFalse
%token OpenBracket "["
%token CloseBracket "]"
%token OpComma ","
%token OpColon ":"
%token OPPAR "("
%token CLOSEPAR ")"
%token OpAssign "<-"
%token OPADD "+"
%token OPSUB "-"
%token OPMUL "*"
%token OpExponente "^"
%token OpLT "<"
%token OpGT ">"
%token OpEqual "=="
%token OpNotEqual "<>"
%token OpLE "<="
%token OpGE ">="
%token <std::string>stringConstant
%token <std::string>charConstant
%token <std::string> ID "id"
%token <int>intConstant "number"
%token ERROR
%left OpEqual OpNotEqual OpLT OpGT OpLE OpGE
%left OPADD OpOr
%left OPMUL OpDiv OpMod OpAnd
%left OpNot OPSUB
%right OpExponente
%type <Ast::Expr*> program expr term factor rvalue variable_decl exponent variable_section assign
%type <Ast::Expr*> statement statement_list argument_list lvalue constants WhileExpr
%type <Ast::Expr*> statement_while_list if_statement else_if_list else_if_statement else_statement
%type <Ast::Expr*> subprogram_call expr_list opt_expr_list
%type <Ast::Expr*> subprogram_decl opt_arguments argument_decl_list
%type <Ast::Expr*> argument_decl
%type <Ast::SubType*> type
%type <IdList*> id_list
%%
input: program ;
program: opt_subtype_definition_section
opt_variable_section
opt_subprogram_decl
"inicio"
opt_eols
statement_list
eols
KwFin
opt_eols
;
opt_subtype_definition_section: subtype_definition_section eols
| %empty;
subtype_definition_section: subtype_definition_section eols KwTipo ID KwEs type
| KwTipo ID KwEs type;
type: KwEntero { $$ = new Ast::Int_Type();}
| KwBooleano { $$ = new Ast::Bool_Type();}
| KwCaracter { $$ = new Ast::Char_Type();}
| array_type;
array_type: KwArreglo OpenBracket intConstant CloseBracket KwDe type;
opt_variable_section: variable_section eols
| %empty;
variable_section: variable_section eols variable_decl
{
$$ = $1;
reinterpret_cast<Ast::VarSection*>($$)->varDecls.push_back($3);
expr_list.push_back($3);
}
| variable_decl
{
list temp;
temp.push_back($1);
$$ = new Ast::VarSection(temp);
expr_list.push_back($1);
};
variable_decl: type id_list { $$ = new Ast::VarDecl($1,$2);};
id_list: id_list OpComma ID
{
$$ = $1;
reinterpret_cast<std::vector<std::string>*>($$)->push_back($3);
}
| ID
{
IdList *tempList = new std::vector<std::string>();
tempList->push_back($1);
$$ = tempList;
};
opt_subprogram_decl: subprogram_decl_list eols
| %empty;
subprogram_decl_list: subprogram_decl_list eols subprogram_decl {sub_list.push_back($3);}
| subprogram_decl {sub_list.push_back($1);};
subprogram_decl: "funcion" ID opt_arguments OpColon type eols
opt_variable_section
KwInicio opt_eols
statement_while_list eols
KwFin { $$ = new Ast::SubProgramDecl($2,$3,$10);}
| KwProcedimiento ID opt_arguments eols
opt_variable_section
KwInicio opt_eols
statement_while_list eols
KwFin { $$ = new Ast::ProcDecl($2,$3,$8);};
opt_arguments: OPPAR argument_decl_list CLOSEPAR {$$ = $2;}
| %empty {$$ = nullptr;};
argument_decl_list: argument_decl_list OpComma argument_decl
{
$$ = $1;
reinterpret_cast<Ast::ExprList*>($$)->expr_list.push_back($3);
}
| argument_decl
{
list temp;
temp.push_back($1);
$$ = new Ast::ExprList(temp);
//expr_list.push_back($1);
};
argument_decl: type ID {$$ = new Ast::ArgDecl($2);}
| KwVar type ID {$$ = new Ast::ArgDecl($3);};
statement_list: statement_list eols statement
{
expr_list.push_back($3);
$$ = $1;
}
| statement
{
expr_list.push_back($1);
$$ = $1;
};
statement_while_list: statement_while_list eols statement
{
$$ = $1;
reinterpret_cast<Ast::ExprList*>($$)->expr_list.push_back($3);
}
| statement
{
list stmts;
stmts.push_back($1);
$$ = new Ast::ExprList(stmts);
};
statement: assign { $$ = $1;}
| KwLlamar ID {$$ = new Ast::SubProgramCall($2,nullptr);}
| KwLlamar subprogram_call {$$ = $2;}
| KwLea lvalue_list
| if_statement
| WhileExpr { $$ = $1;}
| KwEscriba argument_list {$$ = new Ast::PrintExpr($2);}
| KwRepita eols
statement_while_list eols
KwHasta expr
{$$ = new Ast::DoWhileExpr($3,$6);}
| KwPara assign KwHasta expr KwHaga eols
statement_while_list eols
KwFin KwPara
{$$ = new Ast::ForExpr($2,$4,$7);}
| KwRetorne expr {$$ = new Ast::Ret($2);};
WhileExpr: KwMientras expr opt_eols
KwHaga eols
statement_while_list eols
KwFin KwMientras
{$$ = new Ast::WhileExpr($2, $6);}
assign: ID OpAssign expr {$$ = new Ast::AssignExpr($1,$3);};
lvalue_list: lvalue_list OpComma lvalue
| lvalue ;
lvalue: ID {$$ = new Ast::IdExpr($1);}
| ID OpenBracket expr CloseBracket;
opt_expr_list: expr_list {$$ = $1;}
| %empty;
expr_list: expr_list OpComma expr
{
$$ = $1;
reinterpret_cast<Ast::ArgList*>($$)->expr_list.push_back($3);
}
| expr
{
list stmts;
stmts.push_back($1);
$$ = new Ast::ArgList(stmts);
}
;
expr: expr OpEqual term {$$ = new Ast::EqExpr($1,$3);}
| expr OpNotEqual term {$$ = new Ast::NeqExpr($1,$3);}
| expr OpLT term {$$ = new Ast::LtExpr($1,$3);}
| expr OpGT term {$$ = new Ast::GtExpr($1,$3);}
| expr OpLE term {$$ = new Ast::LetExpr($1,$3);}
| expr OpGE term {$$ = new Ast::GetExpr($1,$3);}
| term {$$ = $1;};
term: term OPADD factor {$$ = new Ast::AddExpr($1,$3);}
| term OPSUB factor {$$ = new Ast::SubExpr($1,$3);}
| term OpOr factor {$$ = new Ast::OrExpr($1,$3);}
| factor {$$ = $1;};
factor: factor OPMUL exponent {$$ = new Ast::MulExpr($1,$3);}
| factor OpDiv exponent {$$ = new Ast::DivExpr($1,$3);}
| factor OpMod exponent {$$ = new Ast::ModExpr($1,$3);}
| factor OpAnd exponent {$$ = new Ast::AndExpr($1,$3);}
| exponent {$$ = $1;};
exponent: exponent OpExponente rvalue
| rvalue {$$ = $1;};
rvalue: OPPAR expr CLOSEPAR {$$ = $2;}
| constants {$$ = $1;}
| lvalue {$$ = $1;}
| subprogram_call {$$ = $1;}
| OPSUB expr {$$ = new Ast::UnaryExpr($2);}
| OpNot expr {$$ = new Ast::NotExpr($2);};
constants: intConstant {$$ = new Ast::NumExpr($1);}
| charConstant {$$ = new Ast::CharExpr($1);}
| OpTrue {$$ = new Ast::TrueExpr();}
| OpFalse {$$ = new Ast::FalseExpr();};
subprogram_call: ID OPPAR opt_expr_list CLOSEPAR {$$ = new Ast::SubProgramCall($1,$3);};
argument_list: argument_list OpComma expr
| argument_list OpComma stringConstant
| expr {$$ = $1;}
| stringConstant {$$ = new Ast::StringExpr($1);};
if_statement: KwSi expr opt_eols
KwEntonces opt_eols
statement eols
else_if_list
else_statement
KwFin KwSi
{ $$ = new Ast::IfExpr{$2,$6,$8};};
else_if_list: else_if_list else_if_statement
{
$$ = $1;
reinterpret_cast<Ast::ExprList*>($$)->expr_list.push_back($2);
}
| else_if_statement
{
list stmts;
stmts.push_back($1);
$$ = new Ast::ExprList(stmts);
}
| %empty;
else_if_statement: KwSino KwSi expr opt_eols
KwEntonces opt_eols
statement eols
{$$ = new Ast::ElseIf($3,$7);};
else_statement: KwSino eols statement eols {$$ = new Ast::ElseExpr($3);}
| %empty;
opt_eols: eols
| %empty;
eols: eols EOL
| EOL;
%%