-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfinal.y
433 lines (357 loc) · 7.67 KB
/
final.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
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
%{
#include <bits/stdc++.h>
extern int yylex();
/* extern int yyparse(); */
extern FILE* yyin;
#define TRUE 1
#define FALSE 0
using namespace std;
string nomeArquivo = "codigo_gerado.txt";
vector<string> codigo_gerado;
ofstream fout("output.j");
void geraHeader(void);
void geraFooter(void);
bool checaId(string s);
void defineVar(string id, int tipo);
typedef enum {INT_T} type_enum;
map<string, pair<int,type_enum> > tabelaSimbolos;
int line = 0;
int contaVar = 1;
void yyerror(const char* s);
%}
%error-verbose
%union {
int ival;
float fval;
char *sval;
int bval;
}
/* Declaração dos tokens... */
%token<ival> T_INT
%token<fval> T_REAL
%token<sval> T_STRING
%token<bval> T_BOOL
%token PROG
VAR
START
END
IF
ELSE
THEN
WHILE
DO
FUNC
IDENT
T_TIPO
VOID
T_CLEFT
T_CRIGHT
RETURN
PRINT
READ
T_ATTR
T_TATTR
T_ADDON
T_ENDPROG
SEMICOLON
T_QUIT
%token T_EQUALS
T_LESS
T_GREATER
T_DIFFERS
T_LESSE
T_GREATERE
T_PLUS
T_MINUS
T_MULTIPLY
T_DIVIDE
T_MOD
T_LEFT
T_RIGHT
T_NOT
T_AND
T_OR
%left T_PLUS T_MINUS
%left T_MULTIPLY T_DIVIDE T_MOD
%type<ival> expr siexpr termo fator
%code requires {
#include <vector>
using namespace std;
}
%start programa
%%
programa:
PROG listafuncoes blocoprincipal
| PROG blocoprincipal
;
listafuncoes:
listafuncoes funcao
| funcao
;
funcao:
tiporetorno IDENT T_LEFT declparametros T_RIGHT blocoprincipal
| tiporetorno IDENT T_LEFT T_RIGHT blocoprincipal
;
tiporetorno:
tipo
| VOID
tipo:
T_INT
| T_REAL
| T_STRING
declparametros:
declparametros T_ADDON parametro
| parametro
;
parametro:
T_TIPO IDENT
;
blocoprincipal:
T_CLEFT declaracoes listacmd T_CRIGHT
| T_CLEFT listacmd T_CRIGHT
;
declaracoes:
declaracoes declaracao
| declaracao
;
declaracao:
T_TIPO IDENT SEMICOLON {
string str($2);
defineVar(str,INT_T);
}
;
/* listaid:
listaid T_ADDON IDENT
| IDENT
; */
bloco:
T_CLEFT listacmd T_CRIGHT
;
listacmd:
listacmd comando
| comando
;
comando:
cmdse
| cmdenquanto
| cmdatrib
| cmdescrita
| cmdleitura
| chamadaproc
| retorno
;
retorno:
/* RETURN expressaoaritmetica */
| RETURN T_INT
/* | RETURN T_REAL
| RETURN T_STRING */
;
/* cmdse:
IF expressaologica bloco
| IF expressaologica bloco ELSE bloco
;
cmdenquanto:
WHILE expressaologica bloco
; */
cmdatrib:
/* IDENT T_ATTR expressaoaritmetica */
| IDENT T_ATTR T_INT SEMICOLON {
string str($1);
if (checaId(str)){
if ($3 == INT_T){
escreveCodigo("istore " + to_string(tabelaSimbolos[str].first));
}
} else {
string err = "identificador: "+str+" não foi declarado no escopo";
yyerror(err.c_str());
}
}
/* | IDENT T_ATTR T_REAL
| IDENT T_ATTR T_STRING */
;
cmdescrita:
/* PRINT T_LEFT expressaoaritmetica T_RIGHT */
| PRINT T_LEFT T_INT T_RIGHT
/* | PRINT T_LEFT T_REAL T_RIGHT
| PRINT T_LEFT T_STRING T_RIGHT */
;
cmdleitura:
READ T_LEFT IDENT T_RIGHT
;
chamadaproc:
chamadafuncao
;
chamadafuncao:
IDENT T_LEFT listaparametros T_RIGHT
| IDENT T_LEFT T_RIGHT
listaparametros:
listaparametros T_ADDON expressaoaritmetica
| listaparametros T_ADDON T_INT
/* | listaparametros T_ADDON T_REAL
| listaparametros T_ADDON T_STRING */
/* | expressaoaritmetica */
| T_INT
/* | T_REAL
| T_STRING */
;
/* expressaologica:
expressaorelacional { $$ = $1; }
| T_NOT expressaorelacional { $$ = !$2;}
| expressaorelacional T_AND expressaorelacional { $$ = $1 && $3;}
| expressaorelacional T_OR expressaorelacional { $$ = $1 || $3;}
| T_LEFT expressaologica T_RIGHT
;
expressaorelacional:
expressaoaritmetica T_EQUALS expressaoaritmetica { $$ = $1 == $3;}
| expressaoaritmetica T_LESS expressaoaritmetica { $$ = $1 < $3;}
| expressaoaritmetica T_GREATER expressaoaritmetica { $$ = $1 > $3;}
| expressaoaritmetica T_DIFFERS expressaoaritmetica { $$ = $1 != $3;}
| expressaoaritmetica T_LESSE expressaoaritmetica { $$ = $1 <= $3;}
| expressaoaritmetica T_GREATERE expressaoaritmetica { $$ = $1 >= $3;}
;
expressaoaritmetica:
T_ADDON expr expressaoaritmetica
; */
expr: siexpr { $$ = $1; }
| siexpr T_EQUALS siexpr { $$ = $1 == $3; }
| siexpr T_LESS siexpr { $$ = $1 < $3; }
| siexpr T_GREATER siexpr { $$ = $1 > $3; }
| siexpr T_DIFFERS siexpr { $$ = $1 != $3; }
| siexpr T_LESSE siexpr { $$ = $1 <= $3; }
| siexpr T_GREATERE siexpr { $$ = $1 >= $3; }
;
siexpr: termo { $$ = $1; }
| termo T_PLUS siexpr { $$ = $1 + $3; }
| termo T_MINUS siexpr { $$ = $1 - $3; }
;
termo: fator { $$ = $1; }
| fator T_MULTIPLY termo { $$ = $1 * $3; }
| fator T_DIVIDE termo { $$ = $1 / $3; }
| fator T_MOD termo { $$ = $1 % $3; }
;
fator: T_INT { $$ = $1; }
| T_REAL { $$ = $1; }
| IDENT
| T_LEFT expr T_RIGHT { $$ = $2; }
;
/*
%%
programa:
| PROG IDENT SEMICOLON bloco T_ENDPROG
;
bloco: var
funce
START comando END
;
var:
| VAR IDENT indete T_TATTR IDENT SEMICOLON vare
;
vare:
| IDENT indete T_TATTR IDENT SEMICOLON vare
;
indete:
| T_ADDON IDENT indete
;
funce:
| FUNC IDENT palist SEMICOLON bloco SEMICOLON
;
palist:
| T_LEFT VAR IDENT indete T_TATTR IDENT SEMICOLON var T_RIGHT
;
comando:
| comandoe comando
;
comandoe: IDENT T_ATTR expr SEMICOLON
| IDENT SEMICOLON
| IDENT T_LEFT expr expre T_RIGHT SEMICOLON
| IF expr THEN comando
| IF expr THEN comando ELSE comando
| WHILE expr DO comando
| START comando END SEMICOLON
;
expre:
| T_ADDON expr expre
;
expr: siexpr { $$ = $1; }
| siexpr T_EQUALS siexpr { $$ = $1 == $3; }
| siexpr T_LESS siexpr { $$ = $1 < $3; }
| siexpr T_GREATER siexpr { $$ = $1 > $3; }
| siexpr T_DIFFERS siexpr { $$ = $1 != $3; }
| siexpr T_LESSE siexpr { $$ = $1 <= $3; }
| siexpr T_GREATERE siexpr { $$ = $1 >= $3; }
;
siexpr: termo { $$ = $1; }
| termo T_PLUS siexpr { $$ = $1 + $3; }
| termo T_MINUS siexpr { $$ = $1 - $3; }
;
termo: fator { $$ = $1; }
| fator T_MULTIPLY termo { $$ = $1 * $3; }
| fator T_DIVIDE termo { $$ = $1 / $3; }
| fator T_MOD termo { $$ = $1 % $3; }
;
fator: T_INT { $$ = $1; }
| IDENT
| T_LEFT expr T_RIGHT { $$ = $2; }
;
%%
*/
%%
void geraCodigoArquivo() {
for(int i = 0; i < codigo_gerado.size(); i++) {
fout << codigo_gerado[i] << endl;
}
}
int main() {
/* FILE *f;
f = fopen("codigo_gerado.txt", "r");
nomeArquivo = "codigo_gerado.txt";
if(!f) {
printf("Erro ao abrir o arquivo!\n");
return 0;
} */
//yyin = stdin;
geraHeader();
do {
yyparse();
} while(!feof(yyin));
geraFooter();
geraCodigoArquivo();
return 0;
}
void defineVar(string id, int tipo){
if (checaId(id)){
string err = "Variável: "+id+" já foi declarada";
yyerror(err.c_str());
} else {
if (tipo == INT_T){
escreveCodigo("iconst_0\nistore " + to_string(contaVar))
}
tabelaSimbolos[id] = make_pair(contaVar++,tipo);
}
}
bool checaId(string s){
return (tabelaSimbolos.find(s) != tabelaSimbolos.end());
}
void escreveCodigo(string codigo) {
codigo_gerado.push_back(codigo);
}
void geraHeader() {
escreveCodigo(".source " + nomeArquivo);
escreveCodigo(".class public test\n.super java/lang/Object\n"); //code for defining class
escreveCodigo(".method public <init>()V");
escreveCodigo("aload_0");
escreveCodigo("invokenonvirtual java/lang/Object/<init>()V");
escreveCodigo("return");
escreveCodigo(".end method\n");
escreveCodigo(".method public static main([Ljava/lang/String;)V");
escreveCodigo(".limit locals 100\n.limit stack 100");
}
void geraFooter() {
escreveCodigo("return");
escreveCodigo(".end method");
}
void yyerror(const char* s) {
fprintf(stderr, "Erro de análise (sintática): %s\n", s);
fprintf(stderr, "Erro nas linhas: %d ou %d\n", line, line+1);
exit(1);
}