30 return calloc
(1, sizeof
(struct label
));
38 node
= getsym
(name
, scope
);
39 if
(! node || node
->scope
< scope
) {
40 node
= putsym
(name
, scope
, gen_label
());
42 printf
("%s jah estah definido neste escopo!\n", name
);
47 context_check
(int op
, char *name
)
51 id
= getsym
(name
, scope
);
53 printf
("Simbolo nao declarado: %s\n", name
);
55 gen_code
(op
, id
->offset
);
64 id
= getsym
(name
, scope
);
66 printf
("Fuancao nao declarado: %s\n", name
);
68 /* id->addr points to the GOTO instruction */
69 gen_code
(CALL
, id
->addr
+1);
84 %token
<id
> VARIABLE IDENTIFIER
85 %token
<label
> IF WHILE BREAK CONTINUE
86 %token ELSIF ELSE MY WRT_INT RETURN
95 program: statements
{ gen_code
(HALT
, 0); YYACCEPT; }
98 statements: statements statement
102 statement: declarations
';'
103 | VARIABLE
'=' expression
';' { context_check
(STORE
, $1); }
105 | WRT_INT
'(' INTEGER
')' ';' { gen_code
(LOAD_INT
, $3);
106 gen_code
(WRITE_INT
, 0); }
107 | WRT_INT
'(' VARIABLE
')' ';' { context_check
(LOAD_VAR
, $3);
108 gen_code
(WRITE_INT
, 0); }
109 | IF
'(' expression
')' { $1 = alloc_label
();
110 $1->for_jmp_false
= reserve_loc
(); }
112 statements
'}' { scoperem
(scope
--);
113 back_patch
($1->for_jmp_false
,
116 | WHILE
{ $1 = alloc_label
();
117 $1->for_goto
= gen_label
(); }
118 '(' expression
')' { $1->for_jmp_false
= reserve_loc
(); }
120 statements
'}' { scoperem
(scope
--);
121 gen_code
(GOTO
, $1->for_goto
);
122 back_patch
($1->for_jmp_false
,
125 | IDENTIFIER
{ install
($1);
126 fun_begin
= reserve_loc
();}
128 statements
'}' { scoperem
(scope
--);
130 back_patch
(fun_begin
,
135 declarations: MY VARIABLE
{ install
($2); }
139 id_list: id_list
',' VARIABLE
{ install
($3); }
140 | VARIABLE
{ install
($1); }
143 fun_args_: fun_args |
/* */ ;
145 fun_args: fun_args
',' INTEGER
{ gen_code
(LOAD_INT
, $3); nargs
++; }
146 | fun_args
',' VARIABLE
{ context_check
(LOAD_VAR
, $3); nargs
++; }
147 | INTEGER
{ gen_code
(LOAD_INT
, $1); nargs
++; }
148 | VARIABLE
{ context_check
(LOAD_VAR
, $1); nargs
++; }
151 expression: expression
'+' expression
{ gen_code
(ADD
, 0); }
152 | expression
'-' expression
{ gen_code
(SUB
, 0); }
153 | expression
'*' expression
{ gen_code
(MUL
, 0); }
154 | expression
'/' expression
{ gen_code
(DIV
, 0); }
155 | expression
'%' expression
{ gen_code
(MOD
, 0); }
157 | IDENTIFIER
'(' fun_args_
')' { gen_code
(PUSH_INT
, nargs
);
158 /* +1: after load_int, +2: after call */
159 gen_code
(PUSH_INT
, gen_label
()+2);
162 | VARIABLE
{ context_check
(LOAD_VAR
, $1); }
163 | INTEGER
{ gen_code
(LOAD_INT
, $1); }
164 | RETURN INTEGER
{ gen_code
(LOAD_INT
, $2);
166 | RETURN VARIABLE
{ context_check
(LOAD_VAR
, $2);
175 fprintf
(stderr
, "Uso: %s [argumentos] <programa>\n", pname
);
176 fprintf
(stderr
, "Onde argumentos pode ser:\n");
177 fprintf
(stderr
, "\t-o: Especifica arquivo de saida\n");
178 fprintf
(stderr
, "\t-d: Habilita saida de debugging do parser\n");
179 fprintf
(stderr
, "\t-h: Imprime essa mensagem e finaliza a execucao\n");
187 fprintf
(stderr
, "%s\n", err
);
191 main
(int argc
, char **argv
)
193 char *pname
= argv
[0];
194 char *outfile
= NULL
;
197 while
( (opt
= getopt
(argc
, argv
, "o:dh")) != -1) {
199 case
'd': /* enable parser debugging */
205 case
'h': /* print usage */
211 if
(optind
>= argc
) { /* input file missing */
215 yyin
= fopen
(argv
[optind
], "r");
218 fprintf
(stderr
, "Erro ao abrir %s\n", argv
[optind
]);
222 /* init symbol table */