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
104 %token NE GEQL LEQL GT LT SHFT OR AND NOT
106 %type
<var
> var_dec dim_dec variable pos
107 %type
<fun
> fun_args fun_args_
110 %left EQL NE GEQL LEQL GT LT
119 program: statements
{ gen_code
(HALT
, 0); YYACCEPT; }
122 statements: statements statement
126 statement: declarations
';'
127 | variable
'=' expression
';' { gen_code
(LOAD_OFF
, $1.off
);
128 context_check
(STORE
, $1.id
); }
130 | WRT_INT
'(' INTEGER
')' ';' { gen_code
(LOAD_INT
, $3);
131 gen_code
(WRITE_INT
, 0); }
132 | WRT_INT
'(' variable
')' ';' { gen_code
(LOAD_OFF
, $3.off
);
133 context_check
(LOAD_VAR
, $3.id
);
134 gen_code
(WRITE_INT
, 0); }
135 | IF
'(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
137 statements
'}' { $1.for_else
= reserve_loc
();
138 back_patch
($1.for_jmp_false
,
142 else
{ back_patch
($1.for_else
,
145 | WHILE
{ $1.for_goto
= gen_label
(); }
146 '(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
148 statements
'}' { scoperem
(scope
--);
149 gen_code
(GOTO
, $1.for_goto
);
150 back_patch
($1.for_jmp_false
,
154 back_patch
(nexts
[--npos
],
159 back_patch
(breaks
[--bpos
],
163 | NEXT
';' { nexts
[npos
++] = reserve_loc
(); }
164 | BREAK
';' { breaks
[bpos
++] = reserve_loc
(); }
165 | IDENTIFIER
{ $1.addr
= reserve_loc
();}
167 statements
'}' { scoperem
(scope
--);
169 back_patch
($1.addr
++,
172 install_fun
($1.id
, $1.addr
); }
175 else: ELSE
'{' { scope
++; }
176 statements
'}' { scoperem
(scope
--); }
180 variable: VARIABLE pos
{ $$
= $1;
184 pos: pos
'[' INTEGER
']' { $1.off
*= $3;
186 |
/* empty */ { $$.off
= 1; }
188 var_dec: VARIABLE dim_dec
{ $$
= $1;
193 dim_dec: dim_dec
'[' INTEGER
']' { $1.dim
++;
196 |
/* empty */ { $$.dim
= 1; $$.size
= 1; }
198 declarations: MY var_dec
{ install
($2.id
, $2.dim
, $2.size
); }
202 id_list: id_list
',' var_dec
{ install
($3.id
, $3.dim
, $3.size
); }
203 | var_dec
{ install
($1.id
, $1.dim
, $1.size
); }
206 fun_args_: fun_args
{ $$
= $1; }
207 |
/* */ { $$.nargs
= 0; }
210 fun_args: fun_args
',' INTEGER
{ gen_code
(LOAD_INT
, $3);
211 $$.nargs
= $1.nargs
+ 1; }
212 | fun_args
',' variable
{ gen_code
(LOAD_OFF
, $3.off
);
213 context_check
(LOAD_VAR
, $3.id
);
214 $$.nargs
= $1.nargs
+ 1; }
215 | INTEGER
{ gen_code
(LOAD_INT
, $1); $$.nargs
= 1; }
216 | VARIABLE
{ gen_code
(LOAD_OFF
, $1.off
);
217 context_check
(LOAD_VAR
, $1.id
); $$.nargs
= 1; }
220 expression: expression
'+' expression
{ gen_code
(ADD
, 0); }
221 | expression
'-' expression
{ gen_code
(SUB
, 0); }
222 | expression
'*' expression
{ gen_code
(MUL
, 0); }
223 | expression
'/' expression
{ gen_code
(DIV
, 0); }
224 | expression
'%' expression
{ gen_code
(MOD
, 0); }
225 | expression EQL expression
{ gen_code
(CMP_EQL
, 0); }
226 | expression NE expression
{ gen_code
(CMP_NE
, 0); }
227 | expression GEQL expression
{ gen_code
(CMP_GEQL
, 0); }
228 | expression LEQL expression
{ gen_code
(CMP_LEQL
, 0); }
229 | expression GT expression
{ gen_code
(CMP_GT
, 0); }
230 | expression LT expression
{ gen_code
(CMP_LT
, 0); }
232 | expression OR expression
{ gen_code
(CMP_OR
, 0); }
233 | expression AND expression
{ gen_code
(CMP_AND
, 0); }
234 | NOT expression
{ gen_code
(CMP_NOT
, 0); }
235 | IDENTIFIER
'(' fun_args_
')' { gen_code
(PUSH_INT
, $3.nargs
);
236 /* +1: after load_int, +2: after call */
237 gen_code
(PUSH_INT
, gen_label
()+2);
239 | variable
{ gen_code
(LOAD_OFF
, $1.off
);
240 context_check
(LOAD_VAR
, $1.id
); }
241 | INTEGER
{ gen_code
(LOAD_INT
, $1); }
242 | RETURN INTEGER
{ gen_code
(LOAD_INT
, $2);
244 | RETURN variable
{ gen_code
(LOAD_OFF
, $2.off
);
245 context_check
(LOAD_VAR
, $2.id
);
247 | SHFT
{ gen_code
(SHIFT
, 0); }
255 fprintf
(stderr
, "Uso: %s [argumentos] <programa>\n", pname
);
256 fprintf
(stderr
, "Onde argumentos pode ser:\n");
257 fprintf
(stderr
, "\t-o: Especifica arquivo de saida\n");
258 fprintf
(stderr
, "\t-d: Habilita saida de debugging do parser\n");
259 fprintf
(stderr
, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
267 fprintf
(stderr
, "%s\n", err
);
271 main
(int argc
, char **argv
)
273 char *pname
= argv
[0];
274 char *outfile
= NULL
;
277 while
( (opt
= getopt
(argc
, argv
, "o:dh")) != -1) {
279 case
'd': /* enable parser debugging */
285 case
'h': /* print usage */
291 if
(optind
>= argc
) { /* input file missing */
295 yyin
= fopen
(argv
[optind
], "r");
298 fprintf
(stderr
, "Erro ao abrir %s\n", argv
[optind
]);
302 /* init symbol table */