Fontes no latex usando listings.
[myPerl.git] / parser.y
blob631dd24eab9b941a613c3c652c3515fbd702e8df
1 %{
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <getopt.h>
7 #include "symtab.h"
8 #include "heap.h"
9 #include "code.h"
10 #include "vm.h"
12 #define YYDEBUG 1
14 struct label {
15 int for_goto;
16 int for_jmp_false;
19 void yyerror(char *);
20 int yylex(void);
21 extern FILE *yyin;
23 struct label *
24 alloc_label(void)
26 return calloc(1, sizeof(struct label));
29 void
30 install(char *name)
32 symtab_t *node;
34 node = getsym(name);
35 if (! node) {
36 node = putsym(name);
37 } else {
38 printf("%s jah estah definido!\n", name);
42 void
43 context_check(int op, char *name)
45 symtab_t *id;
47 id = getsym(name);
48 if (! id) {
49 printf("Simbolo nao declarado: %s\n", name);
50 } else {
51 gen_code(op, id->offset);
57 %union {
58 char *id;
59 int ival;
60 struct label *label;
63 %start program
65 %token <ival> INTEGER
66 %token <id> VARIABLE IDENTIFIER
67 %token <label> IF WHILE
68 %token ELSIF ELSE MY WRT_INT
70 %left '+' '-'
71 %left '*' '/' '%'
75 program: statements { gen_code(HALT, 0); YYACCEPT; }
78 statements: statements statement
79 | statement
82 statement: declarations ';'
83 | VARIABLE '=' expression ';' { context_check(STORE, $1); }
84 | expression ';'
85 | WRT_INT '(' INTEGER ')' ';' { gen_code(LOAD_INT, $3);
86 gen_code(WRITE_INT, 0); }
87 | WRT_INT '(' VARIABLE ')' ';' { context_check(LOAD_VAR, $3);
88 gen_code(WRITE_INT, 0); }
89 | IF '(' expression ')' { $1 = alloc_label();
90 $1->for_jmp_false = reserve_loc(); }
91 '{' statements '}' { back_patch($1->for_jmp_false,
92 JMP_FALSE,
93 gen_label()); }
94 | WHILE { $1 = alloc_label();
95 $1->for_goto = gen_label(); }
96 '(' expression ')' { $1->for_jmp_false = reserve_loc(); }
97 '{' statements '}' { gen_code(GOTO, $1->for_goto);
98 back_patch($1->for_jmp_false,
99 JMP_FALSE,
100 gen_label()); }
101 | IDENTIFIER '{' statements '}'
104 declarations: MY VARIABLE { install($2); }
105 | MY '(' id_list ')'
108 id_list: id_list ',' VARIABLE { install($3); }
109 | /* empty */
112 expression: expression '+' expression { gen_code(ADD, 0); }
113 | expression '-' expression { gen_code(SUB, 0); }
114 | expression '*' expression { gen_code(MUL, 0); }
115 | expression '/' expression { gen_code(DIV, 0); }
116 | expression '%' expression { gen_code(MOD, 0); }
117 | IDENTIFIER '(' id_list ')'
118 | VARIABLE { context_check(LOAD_VAR, $1); }
119 | INTEGER { gen_code(LOAD_INT, $1); }
124 void
125 usage(char *pname)
127 fprintf(stderr, "Uso: %s [argumentos] <programa>\n", pname);
128 fprintf(stderr, "Onde argumentos pode ser:\n");
129 fprintf(stderr, "\t-o: Especifica arquivo de saida\n");
130 fprintf(stderr, "\t-d: Habilita saida de debugging do parser\n");
131 fprintf(stderr, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
133 exit(0);
136 void
137 yyerror(char *err)
139 fprintf(stderr, "%s\n", err);
143 main(int argc, char **argv)
145 char *pname = argv[0];
146 char *outfile = NULL;
147 int opt, ret;
149 while ( (opt = getopt(argc, argv, "o:dh")) != -1) {
150 switch(opt) {
151 case 'd': /* enable parser debugging */
152 yydebug = 1;
153 break;
154 case 'o':
155 outfile = optarg;
156 break;
157 case 'h': /* print usage */
158 usage(pname);
159 break;
163 if (optind >= argc) { /* input file missing */
164 usage(pname);
167 yyin = fopen(argv[optind], "r");
168 if (! yyin) {
169 perror("fopen");
170 fprintf(stderr, "Erro ao abrir %s\n", argv[optind]);
171 exit(errno);
174 /* init symbol table */
175 initsym();
177 ret = yyparse();
179 if (outfile)
180 print_code(outfile);
182 vm_loop();
184 return ret;