This repository was archived by the owner on Oct 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.y
More file actions
681 lines (561 loc) · 29.4 KB
/
Copy pathparser.y
File metadata and controls
681 lines (561 loc) · 29.4 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
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
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
%{
#include <stdio.h>
#include <stdarg.h>
#include "structs.h"
#include "sym_table.h"
#include "quad_table.h"
#include "bool_utils.h"
extern int yylineno;
extern FILE *yyin;
sym_table symTable;
quad_table quadTable;
void debug_tables();
void debug_msg(const char *, ...);
void reduction_msg(const char *, ...);
void yyerror(const char *, ...);
%}
/* Tokens */
%token <cadena> TOK_ID TOK_ID_BOOL <numero_entero> TOK_LITERAL_INT <numero_real> TOK_LITERAL_REAL <booleano> TOK_LITERAL_BOOL <caracter> TOK_LITERAL_CHAR <cadena> TOK_LITERAL_STR TOK_COMMENT
/* Reserved words */
%token TOK_R_ACCION TOK_R_ALGORITMO TOK_R_BOOLEANO TOK_R_CADENA TOK_R_CARACTER TOK_R_CONST TOK_R_CONTINUAR TOK_R_DE TOK_R_DEV TOK_R_ES TOK_R_ENT TOK_R_ENTERO TOK_R_FACCION TOK_R_FALGORITMO TOK_R_FCONST TOK_R_FFUNCION TOK_R_FMIENTRAS TOK_R_FPARA TOK_R_FSI TOK_R_FTIPO TOK_R_FTUPLA TOK_R_FUNCION TOK_R_FVAR TOK_R_HACER TOK_R_HASTA TOK_R_MIENTRAS TOK_R_NO TOK_R_PARA TOK_R_REAL TOK_R_REF TOK_R_SAL TOK_R_SI TOK_R_TABLA TOK_R_TIPO TOK_R_TUPLA TOK_R_VAR
%left TOK_R_O TOK_R_Y
/* Operators */
%token TOK_OP_ASSIGNAMENT TOK_OP_SEQU_COMPOS TOK_OP_SEPARATOR TOK_OP_SUBRANGE TOK_OP_VAR_TYPE_DEF TOK_OP_THEN TOK_OP_ELSE_IF TOK_OP_TYPE_DEFINITION TOK_OP_ARRAY_INIT TOK_OP_ARRAY_CLOSE TOK_OP_DOT <op> TOK_OP_REL TOK_OP_PAREN_OPEN TOK_OP_PAREN_CLOSE
%left TOK_OP_PLUS TOK_OP_MINUS
%left TOK_R_MOD TOK_R_DIV
%left TOK_OP_TIMES TOK_OP_DIVIDE
%type <tipo> d_tipo
%type <tipo> tipo_base
%type <tipo> lista_id
%type <exp> expresion
%type <op_a> operando
%type <op_a> exp_a
%type <op_b> operando_b
%type <op_b> exp_b
%type <quad> exp_b_m
%union {
char caracter;
char *cadena;
int booleano;
double numero_real;
long int numero_entero;
variable_tipo tipo;
operador op;
expresion exp;
op_aritmetico op_a;
op_booleano op_b;
int quad;
};
%%
desc_algoritmo: TOK_R_ALGORITMO TOK_ID cabecera_alg bloque_alg TOK_R_FALGORITMO {
reduction_msg("ALGORITMO con nombre %s", $2);
};
cabecera_alg: decl_globales decl_a_f decl_ent_sal TOK_COMMENT {};
bloque_alg: bloque TOK_COMMENT {};
decl_globales: /* vacío */ {}
| declaracion_tipo decl_globales {
reduction_msg("Declaración global de tipos");
}
| declaracion_const decl_globales {
reduction_msg("Declaración global de constantes");
};
decl_a_f: /* vacío */ {}
| accion_d decl_a_f {
reduction_msg("Declaración de acciones");
}
| funcion_d decl_a_f {
reduction_msg("Declaración de funciones");
};
bloque: declaraciones instrucciones {
reduction_msg("Bloque del algoritmo");
};
declaraciones: /* vacío */ {}
| declaracion_tipo declaraciones {}
| declaracion_const declaraciones {}
| declaracion_var declaraciones {};
declaracion_tipo: TOK_R_TIPO lista_d_tipo TOK_R_FTIPO TOK_OP_SEQU_COMPOS {
reduction_msg("Declaración de tipos");
};
declaracion_const: TOK_R_CONST lista_d_cte TOK_R_FCONST TOK_OP_SEQU_COMPOS {
reduction_msg("Declaración de constantes");
};
declaracion_var: TOK_R_VAR lista_d_var TOK_R_FVAR TOK_OP_SEQU_COMPOS {
reduction_msg("Declaración de variables");
};
lista_d_tipo: /* vacío */ {}
| TOK_ID TOK_OP_TYPE_DEFINITION d_tipo TOK_OP_SEQU_COMPOS lista_d_tipo {
reduction_msg("Declaración de tipo %s", variable_tipo_names[$3]);
};
d_tipo: TOK_R_TUPLA lista_campos TOK_R_FTUPLA {
$$ = VAR_DESCONOCIDO;
}
| TOK_R_TABLA TOK_OP_ARRAY_INIT expresion_t TOK_OP_SUBRANGE expresion_t TOK_OP_ARRAY_CLOSE TOK_R_DE d_tipo {
$$ = VAR_DESCONOCIDO;
}
| TOK_ID {
$$ = VAR_DESCONOCIDO;
}
| expresion_t TOK_OP_SUBRANGE expresion_t {
$$ = VAR_DESCONOCIDO;
}
| TOK_R_REF d_tipo {
$$ = VAR_DESCONOCIDO;
}
| tipo_base {
$$ = $1;
};
tipo_base: TOK_R_ENTERO {$$ = VAR_ENTERO;}
| TOK_R_REAL {$$ = VAR_REAL;}
| TOK_R_BOOLEANO {$$ = VAR_BOOLEANO;}
| TOK_R_CARACTER {$$ = VAR_CARACTER;}
| TOK_R_CADENA {$$ = VAR_CADENA;};
expresion_t: expresion {}
| TOK_LITERAL_CHAR {
reduction_msg("Expresión literal de tipo char: %c", $1);
};
lista_campos: /* vacío */ {}
| TOK_ID TOK_OP_VAR_TYPE_DEF d_tipo TOK_OP_SEQU_COMPOS lista_campos {
reduction_msg("Lista de campos");
};
lista_d_cte: /* vacío */ {}
| TOK_ID TOK_OP_TYPE_DEFINITION literal TOK_OP_SEQU_COMPOS lista_d_cte {
reduction_msg("Lista de constantes");
};
literal: TOK_LITERAL_INT { reduction_msg("Literal entero: %ld", $1); }
| TOK_LITERAL_REAL { reduction_msg("Literal real: %f", $1); }
| TOK_LITERAL_BOOL { reduction_msg("Literal booleano: %d", $1); }
| TOK_LITERAL_CHAR { reduction_msg("Literal caracter: %c", $1); }
| TOK_LITERAL_STR { reduction_msg("Literal cadena: %s", $1); };
lista_d_var: /* vacío */ {}
| lista_id TOK_OP_SEQU_COMPOS lista_d_var {
reduction_msg("Lista de variables de tipo %s", variable_tipo_names[$1]);
};
lista_id: TOK_ID TOK_OP_VAR_TYPE_DEF d_tipo {
if (insert_var_TS(&symTable, $1, $3) < 0)
yyerror("Variable '%s' de tipo %s ya definida anteriormente", $1, variable_tipo_names[$3]);
$$ = $3;
}
| TOK_ID_BOOL TOK_OP_VAR_TYPE_DEF d_tipo {
if (insert_var_TS(&symTable, $1, $3) < 0)
yyerror("Variable '%s' de tipo %s ya definida anteriormente", $1, variable_tipo_names[$3]);
$$ = $3;
}
| TOK_ID TOK_OP_SEPARATOR lista_id {
if (insert_var_TS(&symTable, $1, $3) < 0)
yyerror("Variable '%s' de tipo %s ya definida anteriormente", $1, variable_tipo_names[$3]);
$$ = $3;
}
| TOK_ID_BOOL TOK_OP_SEPARATOR lista_id {
if (insert_var_TS(&symTable, $1, $3) < 0)
yyerror("Variable '%s' de tipo %s ya definida anteriormente", $1, variable_tipo_names[$3]);
$$ = $3;
};
decl_ent_sal: decl_ent {}
| decl_sal {}
| decl_ent decl_sal {};
decl_ent: TOK_R_ENT lista_d_var {
reduction_msg("Declaraciones de entrada");
};
decl_sal: TOK_R_SAL lista_d_var {
reduction_msg("Declaraciones de salida");
};
expresion: exp_a {
$$.tipo = EXP_ARITMETICO;
$$.a.id = $1.id;
$$.a.tipo = $1.tipo;
}
| exp_b {
$$.tipo = EXP_BOOLEANO;
$$.b.verdadero = $1.verdadero;
$$.b.falso = $1.falso;
}
| funcion_ll {};
exp_a: exp_a TOK_OP_PLUS exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Suma entera");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_SUMA_ENTERO, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_REAL) {
debug_msg("Suma real");
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_SUMA_REAL, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_REAL) {
debug_msg("Suma real con el primer operador ENTERO");
int op1 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $1.id, OP_NULL, op1);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_SUMA_REAL, op1, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_ENTERO) {
debug_msg("Suma real con el segundo operador ENTERO");
int op2 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $3.id, OP_NULL, op2);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_SUMA_REAL, $1.id, op2, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else {
yyerror("Tipos %s y %s no compatibles para el operador suma",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| exp_a TOK_OP_MINUS exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Resta entera");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_RESTA_ENTERO, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_REAL) {
debug_msg("Resta real");
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_RESTA_REAL, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_REAL) {
debug_msg("Resta real con el primer operador ENTERO");
int op1 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $1.id, OP_NULL, op1);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_RESTA_REAL, op1, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_ENTERO) {
debug_msg("Resta real con el segundo operador ENTERO");
int op2 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $3.id, OP_NULL, op2);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_RESTA_REAL, $1.id, op2, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else {
yyerror("Tipos %s y %s no compatibles para el operador resta",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| exp_a TOK_OP_TIMES exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Multiplicación entera");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_PRODUCTO_ENTERO, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_REAL) {
debug_msg("Multiplicación real");
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_PRODUCTO_REAL, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_REAL) {
debug_msg("Multiplicación real con primer operador ENTERO");
int op1 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $1.id, OP_NULL, op1);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_PRODUCTO_REAL, op1, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_ENTERO) {
debug_msg("Multiplicación real con segundo operador ENTERO");
int op2 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $3.id, OP_NULL, op2);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_PRODUCTO_REAL, $1.id, op2, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else {
yyerror("Tipos %s y %s no compatibles para el operador producto",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| exp_a TOK_OP_DIVIDE exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Divisón real entre ENTEROS");
int op1 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $1.id, OP_NULL, op1);
int op2 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $3.id, OP_NULL, op2);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_DIVISION_REAL, op1, op2, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_REAL) {
debug_msg("Divisón real entre REALES");
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_DIVISION_REAL, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_REAL) {
debug_msg("Divisón real entre ENTERO y REAL");
int op1 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $1.id, OP_NULL, op1);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_DIVISION_REAL, op1, $3.id, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else if ($1.tipo == VAR_REAL && $3.tipo == VAR_ENTERO) {
debug_msg("Divisón real entre REAL y ENTERO");
int op2 = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_ENTERO2REAL, $3.id, OP_NULL, op2);
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_DIVISION_REAL, $1.id, op2, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else {
yyerror("Tipos %s y %s no compatibles para el operador divisón real",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| exp_a TOK_R_MOD exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Módulo");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_MODDULO, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else {
yyerror("Tipos %s y %s no compatibles para el operador módulo",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| exp_a TOK_R_DIV exp_a {
if ($1.tipo == VAR_ENTERO && $3.tipo == VAR_ENTERO) {
debug_msg("Divisón entera");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_DIVISION_ENTERO, $1.id, $3.id, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else {
yyerror("Tipos %s y %s no compatibles para el operador divisón entera",
variable_tipo_names[$1.tipo], variable_tipo_names[$3.tipo]);
}
}
| TOK_OP_PAREN_OPEN exp_a TOK_OP_PAREN_CLOSE {
$$ = $2;
}
| operando {
$$ = $1;
}
| TOK_LITERAL_INT {
$$.id = insert_var_TS(&symTable, "", VAR_ENTERO);
$$.tipo = VAR_ENTERO;
}
| TOK_LITERAL_REAL {
$$.id = insert_var_TS(&symTable, "", VAR_REAL);
$$.tipo = VAR_REAL;
}
| TOK_OP_MINUS exp_a {
if ($2.tipo == VAR_ENTERO) {
debug_msg("Cambio de signo entero");
int result = insert_var_TS(&symTable, "", VAR_ENTERO);
insert_QT(&quadTable, OP_MENOS_ENTERO, $2.id, OP_NULL, result);
$$.id = result;
$$.tipo = VAR_ENTERO;
} else if ($2.tipo == VAR_REAL) {
debug_msg("Cambio de signo real");
int result = insert_var_TS(&symTable, "", VAR_REAL);
insert_QT(&quadTable, OP_MENOS_REAL, $2.id, OP_NULL, result);
$$.id = result;
$$.tipo = VAR_REAL;
} else {
yyerror("Tipo %s no compatible para el operador menos",
variable_tipo_names[$2.tipo]);
}
};
exp_b: exp_b TOK_R_Y exp_b_m exp_b {
backpatch(&quadTable, $1.verdadero, $3);
$$.falso = merge($1.falso, $4.falso);
$$.verdadero = $4.verdadero;
}
| exp_b TOK_R_O exp_b_m exp_b {
backpatch(&quadTable, $1.falso, $3);
$$.verdadero = merge($1.verdadero, $4.verdadero);
$$.falso = $4.falso;
}
| TOK_R_NO exp_b {
$$.verdadero = $2.falso;
$$.falso = $2.verdadero;
}
| operando_b {
$$ = $1;
}
| TOK_LITERAL_BOOL {
// TODO
}
| expresion TOK_OP_REL expresion {
if ($2 > 0) {
$$.verdadero = makelist(quadTable.size);
$$.falso = makelist(quadTable.size + 1);
insert_QT(&quadTable, $2, $1.a.id, $3.a.id, OP_NULL);
insert_QT(&quadTable, OP_GOTO, OP_NULL, OP_NULL, OP_NULL);
} else
yyerror("Operador relacional desconocido");
}
| TOK_OP_PAREN_OPEN exp_b TOK_OP_PAREN_CLOSE {
$$ = $2;
};
exp_b_m: /* vacío */ {
$$ = quadTable.size;
}
operando: TOK_ID {
symbol_node *node = get_var(&symTable, $1);
$$.id = node->id;
$$.tipo = node->sym.var.tipo;
}
| operando TOK_OP_DOT operando {
// TODO
}
| operando TOK_OP_ARRAY_INIT expresion TOK_OP_ARRAY_CLOSE {
// TODO
}
| operando TOK_R_REF {
// TODO
};
operando_b: TOK_ID_BOOL {
symbol_node *node = get_var(&symTable, $1);
$$.verdadero = makelist(quadTable.size);
$$.falso = makelist(quadTable.size + 1);
insert_QT(&quadTable, OP_CONDICIONAL_GOTO, node->id, OP_NULL, OP_NULL);
insert_QT(&quadTable, OP_GOTO, OP_NULL, OP_NULL, OP_NULL);
}
| operando_b TOK_OP_DOT operando_b {
// TODO
}
| operando_b TOK_OP_ARRAY_INIT expresion TOK_OP_ARRAY_CLOSE {
// TODO
}
| operando_b TOK_R_REF {
// TODO
};
instrucciones: instruccion TOK_OP_SEQU_COMPOS instrucciones {}
| instruccion {};
instruccion: TOK_R_CONTINUAR {}
| asignacion {}
| alternativa {}
| iteracion {}
| accion_ll {};
asignacion: operando TOK_OP_ASSIGNAMENT expresion {
if ($3.tipo == EXP_ARITMETICO && $1.tipo == $3.a.tipo) {
debug_msg("Asignación aritmética");
insert_QT(&quadTable, OP_ASIGNACION, $3.a.id, OP_NULL, $1.id);
} else
yyerror("No se puede asignar un valor de tipo %s a una variable de tipo %s",
variable_tipo_names[$3.a.tipo], variable_tipo_names[$1.tipo]);
}
| operando_b TOK_OP_ASSIGNAMENT expresion {
if ($3.tipo == EXP_BOOLEANO) {
debug_msg("Asignación booleana");
$1.verdadero = $3.b.verdadero;
$1.falso = $3.b.falso;
} else
yyerror("No se puede asignar un valor de tipo %s a una variable de tipo BOOLEANO",
variable_tipo_names[$3.a.tipo]);
};
alternativa: TOK_R_SI expresion TOK_OP_THEN instrucciones lista_opciones TOK_R_FSI {
reduction_msg("Instrucción SI");
};
lista_opciones: /* vacío */ {}
| TOK_OP_ELSE_IF expresion TOK_OP_THEN instrucciones lista_opciones {
reduction_msg("Instrucción SI NO");
};
iteracion: it_cota_fija {}
| it_cota_exp {};
it_cota_fija: TOK_R_PARA TOK_ID TOK_OP_ASSIGNAMENT expresion TOK_R_HASTA expresion TOK_R_HACER instrucciones TOK_R_FPARA {
reduction_msg("Instrucción PARA con cota fija");
};
it_cota_exp: TOK_R_MIENTRAS expresion TOK_R_HACER instrucciones TOK_R_FMIENTRAS {
reduction_msg("Instrucción PARA con expresión como cota");
};
accion_d: TOK_R_ACCION a_cabecera bloque TOK_R_FACCION {
reduction_msg("Acción");
};
funcion_d: TOK_R_FUNCION f_cabecera bloque TOK_R_DEV expresion TOK_R_FFUNCION {
reduction_msg("Función");
};
a_cabecera: TOK_ID TOK_OP_PAREN_OPEN d_par_form TOK_OP_PAREN_CLOSE TOK_OP_SEQU_COMPOS {
reduction_msg("Cabecera de acción con nombre %s", $1);
};
f_cabecera: TOK_ID TOK_OP_PAREN_OPEN lista_d_var TOK_OP_PAREN_CLOSE TOK_R_DEV d_tipo TOK_OP_SEQU_COMPOS {
reduction_msg("Cabecera de función con nombre %s", $1);
};
d_par_form: /* vacío */ {}
| d_p_form TOK_OP_SEQU_COMPOS d_par_form {
reduction_msg("d_par_form");
};
d_p_form: TOK_R_ENT lista_id TOK_OP_VAR_TYPE_DEF d_tipo {
reduction_msg("d_p_form");
}
| TOK_R_SI lista_id TOK_OP_VAR_TYPE_DEF d_tipo {
reduction_msg("d_p_form");
}
| TOK_R_ES lista_id TOK_OP_VAR_TYPE_DEF d_tipo {
reduction_msg("d_p_form");
};
accion_ll: TOK_ID TOK_OP_PAREN_OPEN l_ll TOK_OP_PAREN_CLOSE {
reduction_msg("accion_ll: %s", $1);
};
funcion_ll: TOK_ID TOK_OP_PAREN_OPEN l_ll TOK_OP_PAREN_CLOSE {
reduction_msg("funcion_ll: %s", $1);
};
l_ll: expresion TOK_OP_SEPARATOR l_ll {
reduction_msg("l_ll");
}
| expresion {
reduction_msg("l_ll");
};
%%
int main(int argc, char **argv) {
++argv, --argc;
yyin = (argc > 0) ? fopen(argv[0], "r") : stdin;
if (yyin == NULL) {
reduction_msg("I can't input file!");
return -1;
}
init_TS(&symTable);
init_QT(&quadTable);
yyparse();
debug_tables();
return 0;
}
void debug_tables() {
#if DEBUG
fprintf(stdout, "\033[36m-----------------------------------------------------------------------\033[0m\n");
fprintf(stdout, "\033[36m\nDEBUG: Quad Table\033[0m\n");
print_QT(&quadTable);
fprintf(stdout, "\033[36m\nDEBUG: Sym Table \033[0m\n");
print_TS(&symTable);
fprintf(stdout, "\033[36m-----------------------------------------------------------------------\033[0m\n");
#endif
}
void debug_msg(const char *format, ...) {
#if DEBUG
va_list args;
fprintf(stdout, "\033[36mDEBUG: ");
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, "\033[0m\n");
#endif
}
void reduction_msg(const char *format, ...) {
#if DEBUG
va_list args;
fprintf(stdout, "\033[32mREDUCCION: ");
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
fprintf(stdout, "\033[0m\n");
#endif
}
void yyerror(const char *format, ...) {
va_list args;
fprintf(stderr, "\033[31mERROR en la linea %d: ", yylineno);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\033[0m\n");
}