24 install
(char *name
, int dim
, int size
)
28 node
= getsym
(name
, scope
);
29 if
(! node || node
->scope
< scope
) {
30 node
= putsym
(name
, scope
, 0, dim
, size
);
32 printf
("%s jah estah definido neste escopo!\n", name
);
37 install_fun
(char *name
, int addr
)
41 node
= getsym
(name
, scope
);
42 if
(! node || node
->scope
< scope
) {
43 node
= putsym
(name
, scope
, addr
, 0, 0);
45 printf
("%s jah estah definido neste escopo!\n", name
);
50 context_check
(int op
, char *name
)
54 id
= getsym
(name
, scope
);
56 printf
("Simbolo nao declarado: %s\n", name
);
58 gen_code
(op
, id
->offset
);
67 id
= getsym
(name
, scope
);
69 printf
("Fuancao nao declarado: %s\n", name
);
71 gen_code
(CALL
, id
->addr
);
100 %token
<fun
> IDENTIFIER
101 %token
<var
> VARIABLE
102 %token
<label
> IF WHILE BREAK NEXT
103 %token ELSIF ELSE MY WRT_INT RETURN EQL NE GEQL LEQL GT LT
105 %type
<var
> var_dec dim_dec variable pos
106 %type
<fun
> fun_args fun_args_
109 %left EQL NE GEQL LEQL GT LT
116 program: statements
{ gen_code
(HALT
, 0); YYACCEPT; }
119 statements: statements statement
123 statement: declarations
';'
124 | variable
'=' expression
';' { gen_code
(LOAD_OFF
, $1.off
);
125 context_check
(STORE
, $1.id
); }
127 | WRT_INT
'(' INTEGER
')' ';' { gen_code
(LOAD_INT
, $3);
128 gen_code
(WRITE_INT
, 0); }
129 | WRT_INT
'(' variable
')' ';' { gen_code
(LOAD_OFF
, $3.off
);
130 context_check
(LOAD_VAR
, $3.id
);
131 gen_code
(WRITE_INT
, 0); }
132 | IF
'(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
134 statements
'}' { $1.for_else
= reserve_loc
();
135 back_patch
($1.for_jmp_false
,
139 else
{ back_patch
($1.for_else
,
142 | WHILE
{ $1.for_goto
= gen_label
(); }
143 '(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
145 statements
'}' { scoperem
(scope
--);
146 gen_code
(GOTO
, $1.for_goto
);
147 back_patch
($1.for_jmp_false
,
151 back_patch
(nexts
[--npos
],
156 back_patch
(breaks
[--bpos
],
160 | NEXT
';' { nexts
[npos
++] = reserve_loc
(); }
161 | BREAK
';' { breaks
[bpos
++] = reserve_loc
(); }
162 | IDENTIFIER
{ $1.addr
= reserve_loc
();}
164 statements
'}' { scoperem
(scope
--);
166 back_patch
($1.addr
++,
169 install_fun
($1.id
, $1.addr
); }
172 else: ELSE
'{' { scope
++; }
173 statements
'}' { scoperem
(scope
--); }
177 variable: VARIABLE pos
{ $$
= $1;
181 pos: pos
'[' INTEGER
']' { $1.off
*= $3;
183 |
/* empty */ { $$.off
= 1; }
185 var_dec: VARIABLE dim_dec
{ $$
= $1;
190 dim_dec: dim_dec
'[' INTEGER
']' { $1.dim
++;
193 |
/* empty */ { $$.dim
= 1; $$.size
= 1; }
195 declarations: MY var_dec
{ install
($2.id
, $2.dim
, $2.size
); }
199 id_list: id_list
',' var_dec
{ install
($3.id
, $3.dim
, $3.size
); }
200 | var_dec
{ install
($1.id
, $1.dim
, $1.size
); }
203 fun_args_: fun_args
{ $$
= $1; }
204 |
/* */ { $$.nargs
= 0; }
207 fun_args: fun_args
',' INTEGER
{ gen_code
(LOAD_INT
, $3);
208 $$.nargs
= $1.nargs
+ 1; }
209 | fun_args
',' variable
{ gen_code
(LOAD_OFF
, $3.off
);
210 context_check
(LOAD_VAR
, $3.id
);
211 $$.nargs
= $1.nargs
+ 1; }
212 | INTEGER
{ gen_code
(LOAD_INT
, $1); $$.nargs
= 1; }
213 | VARIABLE
{ gen_code
(LOAD_OFF
, $1.off
);
214 context_check
(LOAD_VAR
, $1.id
); $$.nargs
= 1; }
217 expression: expression
'+' expression
{ gen_code
(ADD
, 0); }
218 | expression
'-' expression
{ gen_code
(SUB
, 0); }
219 | expression
'*' expression
{ gen_code
(MUL
, 0); }
220 | expression
'/' expression
{ gen_code
(DIV
, 0); }
221 | expression
'%' expression
{ gen_code
(MOD
, 0); }
222 | expression EQL expression
{ gen_code
(CMP_EQL
, 0); }
223 | expression NE expression
{ gen_code
(CMP_NE
, 0); }
224 | expression GEQL expression
{ gen_code
(CMP_GEQL
, 0); }
225 | expression LEQL expression
{ gen_code
(CMP_LEQL
, 0); }
226 | expression GT expression
{ gen_code
(CMP_GT
, 0); }
227 | expression LT expression
{ gen_code
(CMP_LT
, 0); }
229 | IDENTIFIER
'(' fun_args_
')' { gen_code
(PUSH_INT
, $3.nargs
);
230 /* +1: after load_int, +2: after call */
231 gen_code
(PUSH_INT
, gen_label
()+2);
233 | variable
{ gen_code
(LOAD_OFF
, $1.off
);
234 context_check
(LOAD_VAR
, $1.id
); }
235 | INTEGER
{ gen_code
(LOAD_INT
, $1); }
236 | RETURN INTEGER
{ gen_code
(LOAD_INT
, $2);
238 | RETURN variable
{ gen_code
(LOAD_OFF
, $2.off
);
239 context_check
(LOAD_VAR
, $2.id
);
248 fprintf
(stderr
, "Uso: %s [argumentos] <programa>\n", pname
);
249 fprintf
(stderr
, "Onde argumentos pode ser:\n");
250 fprintf
(stderr
, "\t-o: Especifica arquivo de saida\n");
251 fprintf
(stderr
, "\t-d: Habilita saida de debugging do parser\n");
252 fprintf
(stderr
, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
260 fprintf
(stderr
, "%s\n", err
);
264 main
(int argc
, char **argv
)
266 char *pname
= argv
[0];
267 char *outfile
= NULL
;
270 while
( (opt
= getopt
(argc
, argv
, "o:dh")) != -1) {
272 case
'd': /* enable parser debugging */
278 case
'h': /* print usage */
284 if
(optind
>= argc
) { /* input file missing */
288 yyin
= fopen
(argv
[optind
], "r");
291 fprintf
(stderr
, "Erro ao abrir %s\n", argv
[optind
]);
295 /* init symbol table */