24 node
= getsym
(name
, scope
);
25 if
(! node || node
->scope
< scope
) {
26 node
= putsym
(name
, scope
, 0);
28 printf
("%s jah estah definido neste escopo!\n", name
);
33 install_fun
(char *name
, int addr
)
37 node
= getsym
(name
, scope
);
38 if
(! node || node
->scope
< scope
) {
39 node
= putsym
(name
, scope
, addr
);
41 printf
("%s jah estah definido neste escopo!\n", name
);
46 context_check
(int op
, char *name
)
50 id
= getsym
(name
, scope
);
52 printf
("Simbolo nao declarado: %s\n", name
);
54 gen_code
(op
, id
->offset
);
63 id
= getsym
(name
, scope
);
65 printf
("Fuancao nao declarado: %s\n", name
);
67 gen_code
(CALL
, id
->addr
);
92 %token
<fun
> IDENTIFIER
94 %token
<label
> IF WHILE BREAK CONTINUE
95 %token ELSIF ELSE MY WRT_INT RETURN
97 %type
<fun
> fun_args fun_args_
106 program: statements
{ gen_code
(HALT
, 0); YYACCEPT; }
109 statements: statements statement
113 statement: declarations
';'
114 | VARIABLE
'=' expression
';' { context_check
(STORE
, $1.id
); }
116 | WRT_INT
'(' INTEGER
')' ';' { gen_code
(LOAD_INT
, $3);
117 gen_code
(WRITE_INT
, 0); }
118 | WRT_INT
'(' VARIABLE
')' ';' { context_check
(LOAD_VAR
, $3.id
);
119 gen_code
(WRITE_INT
, 0); }
120 | IF
'(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
122 statements
'}' { scoperem
(scope
--);
123 back_patch
($1.for_jmp_false
,
126 | WHILE
{ $1.for_goto
= gen_label
(); }
127 '(' expression
')' { $1.for_jmp_false
= reserve_loc
(); }
129 statements
'}' { scoperem
(scope
--);
130 gen_code
(GOTO
, $1.for_goto
);
131 back_patch
($1.for_jmp_false
,
134 | IDENTIFIER
{ $1.addr
= reserve_loc
();}
136 statements
'}' { scoperem
(scope
--);
138 back_patch
($1.addr
++,
141 install_fun
($1.id
, $1.addr
); }
144 declarations: MY VARIABLE
{ install
($2.id
); }
148 id_list: id_list
',' VARIABLE
{ install
($3.id
); }
149 | VARIABLE
{ install
($1.id
); }
152 fun_args_: fun_args
{ $$
= $1; }
153 |
/* */ { $$.nargs
= 0; }
156 fun_args: fun_args
',' INTEGER
{ gen_code
(LOAD_INT
, $3);
157 $$.nargs
= $1.nargs
+ 1; }
158 | fun_args
',' VARIABLE
{ context_check
(LOAD_VAR
, $3.id
);
159 $$.nargs
= $1.nargs
+ 1; }
160 | INTEGER
{ gen_code
(LOAD_INT
, $1); $$.nargs
= 1; }
161 | VARIABLE
{ context_check
(LOAD_VAR
, $1.id
); $$.nargs
= 1; }
164 expression: expression
'+' expression
{ gen_code
(ADD
, 0); }
165 | expression
'-' expression
{ gen_code
(SUB
, 0); }
166 | expression
'*' expression
{ gen_code
(MUL
, 0); }
167 | expression
'/' expression
{ gen_code
(DIV
, 0); }
168 | expression
'%' expression
{ gen_code
(MOD
, 0); }
170 | IDENTIFIER
'(' fun_args_
')' { gen_code
(PUSH_INT
, $3.nargs
);
171 /* +1: after load_int, +2: after call */
172 gen_code
(PUSH_INT
, gen_label
()+2);
174 | VARIABLE
{ context_check
(LOAD_VAR
, $1.id
); }
175 | INTEGER
{ gen_code
(LOAD_INT
, $1); }
176 | RETURN INTEGER
{ gen_code
(LOAD_INT
, $2);
178 | RETURN VARIABLE
{ context_check
(LOAD_VAR
, $2.id
);
187 fprintf
(stderr
, "Uso: %s [argumentos] <programa>\n", pname
);
188 fprintf
(stderr
, "Onde argumentos pode ser:\n");
189 fprintf
(stderr
, "\t-o: Especifica arquivo de saida\n");
190 fprintf
(stderr
, "\t-d: Habilita saida de debugging do parser\n");
191 fprintf
(stderr
, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
199 fprintf
(stderr
, "%s\n", err
);
203 main
(int argc
, char **argv
)
205 char *pname
= argv
[0];
206 char *outfile
= NULL
;
209 while
( (opt
= getopt
(argc
, argv
, "o:dh")) != -1) {
211 case
'd': /* enable parser debugging */
217 case
'h': /* print usage */
223 if
(optind
>= argc
) { /* input file missing */
227 yyin
= fopen
(argv
[optind
], "r");
230 fprintf
(stderr
, "Erro ao abrir %s\n", argv
[optind
]);
234 /* init symbol table */