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
);
99 %token
<fun
> IDENTIFIER
100 %token
<var
> VARIABLE
101 %token
<label
> IF WHILE BREAK NEXT
102 %token ELSIF ELSE MY WRT_INT RETURN
104 %type
<var
> var_dec dim_dec variable pos
105 %type
<fun
> fun_args fun_args_
114 program: statements
{ gen_code
(HALT
, 0); YYACCEPT; }
117 statements: statements statement
121 statement: declarations
';'
122 | variable
'=' expression
';' { gen_code
(LOAD_OFF
, $1.off
);
123 context_check
(STORE
, $1.id
); }
125 | WRT_INT
'(' INTEGER
')' ';' { gen_code
(LOAD_INT
, $3);
126 gen_code
(WRITE_INT
, 0); }
127 | WRT_INT
'(' variable
')' ';' { gen_code
(LOAD_OFF
, $3.off
);
128 context_check
(LOAD_VAR
, $3.id
);
129 gen_code
(WRITE_INT
, 0); }
130 | IF
'(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
132 statements
'}' { scoperem
(scope
--);
133 back_patch
($1.for_jmp_false
,
136 | WHILE
{ $1.for_goto
= gen_label
(); }
137 '(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
139 statements
'}' { scoperem
(scope
--);
140 gen_code
(GOTO
, $1.for_goto
);
141 back_patch
($1.for_jmp_false
,
145 back_patch
(nexts
[--npos
],
150 back_patch
(breaks
[--bpos
],
154 | NEXT
';' { nexts
[npos
++] = reserve_loc
(); }
155 | BREAK
';' { breaks
[bpos
++] = reserve_loc
(); }
156 | IDENTIFIER
{ $1.addr
= reserve_loc
();}
158 statements
'}' { scoperem
(scope
--);
160 back_patch
($1.addr
++,
163 install_fun
($1.id
, $1.addr
); }
166 variable: VARIABLE pos
{ $$
= $1;
170 pos: pos
'[' INTEGER
']' { $1.off
*= $3;
172 |
/* empty */ { $$.off
= 1; }
174 var_dec: VARIABLE dim_dec
{ $$
= $1;
179 dim_dec: dim_dec
'[' INTEGER
']' { $1.dim
++;
182 |
/* empty */ { $$.dim
= 1; $$.size
= 1; }
184 declarations: MY var_dec
{ install
($2.id
, $2.dim
, $2.size
); }
188 id_list: id_list
',' var_dec
{ install
($3.id
, $3.dim
, $3.size
); }
189 | var_dec
{ install
($1.id
, $1.dim
, $1.size
); }
192 fun_args_: fun_args
{ $$
= $1; }
193 |
/* */ { $$.nargs
= 0; }
196 fun_args: fun_args
',' INTEGER
{ gen_code
(LOAD_INT
, $3);
197 $$.nargs
= $1.nargs
+ 1; }
198 | fun_args
',' variable
{ gen_code
(LOAD_OFF
, $3.off
);
199 context_check
(LOAD_VAR
, $3.id
);
200 $$.nargs
= $1.nargs
+ 1; }
201 | INTEGER
{ gen_code
(LOAD_INT
, $1); $$.nargs
= 1; }
202 | VARIABLE
{ gen_code
(LOAD_OFF
, $1.off
);
203 context_check
(LOAD_VAR
, $1.id
); $$.nargs
= 1; }
206 expression: expression
'+' expression
{ gen_code
(ADD
, 0); }
207 | expression
'-' expression
{ gen_code
(SUB
, 0); }
208 | expression
'*' expression
{ gen_code
(MUL
, 0); }
209 | expression
'/' expression
{ gen_code
(DIV
, 0); }
210 | expression
'%' expression
{ gen_code
(MOD
, 0); }
212 | IDENTIFIER
'(' fun_args_
')' { gen_code
(PUSH_INT
, $3.nargs
);
213 /* +1: after load_int, +2: after call */
214 gen_code
(PUSH_INT
, gen_label
()+2);
216 | variable
{ gen_code
(LOAD_OFF
, $1.off
);
217 context_check
(LOAD_VAR
, $1.id
); }
218 | INTEGER
{ gen_code
(LOAD_INT
, $1); }
219 | RETURN INTEGER
{ gen_code
(LOAD_INT
, $2);
221 | RETURN variable
{ gen_code
(LOAD_OFF
, $2.off
);
222 context_check
(LOAD_VAR
, $2.id
);
231 fprintf
(stderr
, "Uso: %s [argumentos] <programa>\n", pname
);
232 fprintf
(stderr
, "Onde argumentos pode ser:\n");
233 fprintf
(stderr
, "\t-o: Especifica arquivo de saida\n");
234 fprintf
(stderr
, "\t-d: Habilita saida de debugging do parser\n");
235 fprintf
(stderr
, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
243 fprintf
(stderr
, "%s\n", err
);
247 main
(int argc
, char **argv
)
249 char *pname
= argv
[0];
250 char *outfile
= NULL
;
253 while
( (opt
= getopt
(argc
, argv
, "o:dh")) != -1) {
255 case
'd': /* enable parser debugging */
261 case
'h': /* print usage */
267 if
(optind
>= argc
) { /* input file missing */
271 yyin
= fopen
(argv
[optind
], "r");
274 fprintf
(stderr
, "Erro ao abrir %s\n", argv
[optind
]);
278 /* init symbol table */