codea: mehr debug code
[uebersetzerbau-ss10.git] / codea / parser.y
1 %{
2         #include <stdio.h>
3         #include <stdlib.h>
4         #include <string.h>
5         #include "symtable.h"
6         #include "chelper.h"
7         #include "tree.h"
8 %}
9
10 %start Input
11 %token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS IDENT NUM ASSIGN
12
13 @macro xxputsin(xx,)
14         @i xx = @Statement.sin@;
15 @end
16
17 @macro statinout()
18         @i @Statement.sout@ = @Statement.sin@;
19         /* das
20          *> xxputsin(@Statement.sout@,)
21          * geht nicht, weil verschachtelte macros deaktiviert sind */
22 @end
23
24 @autoinh s
25 @autosyn node imm exprcount
26
27 @attributes { char *name; } IDENT
28 @attributes { long val; } NUM
29 @attributes { struct symbol *f; int parms; } Parms
30 @attributes { struct symbol *f; } FeldID Structdef Program
31 @attributes { struct symbol *s; } Methoddef Statseq Exprs
32 @attributes { struct symbol *s; struct treenode *node; short imm; int exprcount; } Expr Minusterm Term
33 @attributes { struct symbol *s; struct treenode *node; } Lexpr Multerm Orterm Feld
34 @attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement
35
36 @traversal @postorder c
37 @traversal @preorder reg
38 @traversal @postorder gen
39
40 %%
41 Input:
42           Program
43           @{
44             @i @Program.f@ = tab_new();
45             @gen @revorder(1) printf("\t.text\n");
46           @}
47         ;
48
49 Program:
50           Methoddef ';' Program
51           @{
52             @i @Methoddef.s@ = @Program.0.f@;
53             @i @Program.1.f@ = @Program.0.f@;
54           @}
55
56         | Structdef ';' Program
57           @{
58             @i @Program.1.f@ = tab_merge(@Program.0.f@, @Structdef.f@, 1);
59           @}
60         |
61         ;
62
63 Methoddef:
64           METHOD IDENT '(' Parms ')' Statseq END
65           @{
66             @i @Parms.parms@ = 1;
67             @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
68             @gen @revorder(1) func_header(@IDENT.name@);
69           @}
70         ;
71
72 Structdef:
73           STRUCT FeldID END
74           @{
75             @i @Structdef.f@ = @FeldID.f@;
76           @}
77         ;
78
79 Parms:
80           /* lokale Vars werden in Statement in die tabelle eingefuegt */
81           IDENT Parms
82           @{
83             @i @Parms.1.parms@ = @Parms.parms@ + 1;
84             @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_PARM, 1, @Parms.parms@);
85           @}
86
87         |
88           @{
89             @i @Parms.f@ = tab_new();
90           @}
91         ;
92
93 FeldID:
94           IDENT FeldID
95           @{
96             @i @FeldID.0.f@ = tab_add_symbol(@FeldID.1.f@, @IDENT.name@, S_FIELD, 1, -1);
97           @}
98
99         |
100           @{
101             @i @FeldID.f@ = tab_new();
102           @}
103         ;
104
105 Statseq:
106           Statement ';' Statseq
107           @{
108                 @i @Statement.sin@ = @Statseq.0.s@;
109                 @i @Statseq.1.s@ = @Statement.sout@;
110                 @gen write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1);
111           @}
112
113         |
114         ;
115
116 Statement:
117           Lexpr ASSIGN Expr
118           @{
119                 statinout()
120                 xxputsin(@Lexpr.s@,)
121                 xxputsin(@Expr.s@,)
122             @i @Statement.node@ = TREENULL;
123           @}
124
125         | VAR IDENT ASSIGN Expr
126           @{
127                 /* tab_clone ist hier noetig, vgl. folgendes statement
128                  * > var x := x - 1; */
129                 @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1, -1);
130                 xxputsin(@Expr.s@,)
131             @i @Statement.node@ = TREENULL;
132           @}
133
134         | Expr
135           @{
136                 statinout()
137                 xxputsin(@Expr.s@,)
138             @i @Statement.node@ = TREENULL;
139           @}
140
141         | IF Expr THEN Statseq END
142           @{
143                 statinout()
144                 xxputsin(@Expr.s@,)
145                 xxputsin(@Statseq.s@,)
146             @i @Statement.node@ = TREENULL;
147           @}
148
149         | IF Expr THEN Statseq ELSE Statseq END
150           @{
151                 statinout()
152                 xxputsin(@Expr.s@,)
153                 xxputsin(@Statseq.0.s@,)
154                 xxputsin(@Statseq.1.s@,)
155             @i @Statement.node@ = TREENULL;
156           @}
157
158         | WHILE Expr DO Statseq END
159           @{
160                 statinout()
161                 xxputsin(@Expr.s@,)
162                 xxputsin(@Statseq.s@,)
163             @i @Statement.node@ = TREENULL;
164           @}
165
166         | RETURN Expr
167           @{
168                 statinout()
169                 xxputsin(@Expr.s@,)
170                 @i @Statement.node@ = new_node(O_RET, @Expr.node@, TREENULL, 0);
171                 @reg @Statement.node@->reg = next_reg((char *)NULL, 0); @Expr.node@->reg = @Statement.node@->reg;
172           @}
173         ;
174
175 Lexpr:
176           IDENT
177           @{
178             @i @Lexpr.node@ = TREENULL;
179             @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM);
180           @}
181
182         | Feld
183         ;
184
185 Feld: Term '.' IDENT
186           @{
187             @c check(@Feld.s@, @IDENT.name@, S_FIELD);
188             @i @Feld.node@ = TREENULL;
189           @}
190         ;
191
192 Expr:
193           Term
194           @{
195             @reg @Term.node@->reg = @Expr.node@->reg;
196                 @i @Expr.exprcount@ = 1 + @Term.exprcount@; fprintf(stderr, "(Expr)- Term\n");
197           @}
198
199         | NOT Term
200           @{
201             @i @Expr.node@ = TREENULL;
202                 @i @Expr.exprcount@ = 1 + @Term.exprcount@; fprintf(stderr, "(Expr)- NOT Term\n");
203           @}
204
205         | Term Minusterm
206           @{
207                 @i @Expr.exprcount@ = 1 + @Term.exprcount@ + @Minusterm.exprcount@; fprintf(stderr, "(Expr)- Term Minusterm\n");
208             @i @Expr.node@ = new_node(O_SUB, @Minusterm.node@, @Term.node@, @Expr.exprcount@);
209                 @i @Expr.imm@ = @Term.imm@ && @Minusterm.imm@;
210
211                 @reg {
212                         /* TODO */
213                         @Term.node@->reg = @Expr.node@->reg;
214                         @Term.node@->skip = 1;
215                         @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip);
216                 }
217           @}
218
219         | Term Multerm
220           @{
221             @i @Expr.node@ = TREENULL;
222                 @i @Expr.exprcount@ = 1 + @Term.exprcount@; fprintf(stderr, "(Expr)- Term Multerm\n");
223           @}
224
225         | Term Orterm
226           @{
227             @i @Expr.node@ = TREENULL;
228                 @i @Expr.exprcount@ = 1 + @Term.exprcount@; fprintf(stderr, "(Expr)- Term OrTerm\n");
229           @}
230
231         | Term '<' Term
232           @{
233             @i @Expr.node@ = TREENULL;
234                 /* das is bloedsinn atm */ @i @Expr.imm@ = @Term.0.imm@ && @Term.1.imm@;
235                 @i @Expr.exprcount@ = 1 + @Term.0.exprcount@ + @Term.1.exprcount@; fprintf(stderr, "(Expr)- Term < Term\n");
236           @}
237
238         | Term '=' Term
239           @{
240             @i @Expr.node@ = TREENULL;
241                 /* das is bloedsinn atm */ @i @Expr.imm@ = @Term.0.imm@ && @Term.1.imm@;
242                 @i @Expr.exprcount@ = 1 + @Term.0.exprcount@ + @Term.1.exprcount@; fprintf(stderr, "(Expr)- Term = Term\n");
243           @}
244         ;
245
246 Minusterm:
247           '-' Term Minusterm
248           @{
249                 @i @Minusterm.0.exprcount@ = 1 + @Term.exprcount@ + @Minusterm.1.exprcount@; fprintf(stderr, "(Minusterm)- - Term Minusterm\n");
250             @i @Minusterm.node@ = new_node(O_ADD, @Minusterm.1.node@, @Term.node@, @Minusterm.0.exprcount@);
251                 @i @Minusterm.imm@ = @Term.imm@ && @Minusterm.1.imm@;
252
253             @reg {
254                         @Minusterm.1.node@->reg = @Minusterm.node@->reg;
255                         @Term.node@->reg = next_reg(@Minusterm.1.node@->reg, @Minusterm.node@->skip);
256                 }
257           @}
258
259         | '-' Term
260           @{
261                 @i @Minusterm.exprcount@ = 1 + @Term.exprcount@; fprintf(stderr, "(Minusterm)- - Term\n");
262             @reg @Term.node@->reg = @Minusterm.node@->reg;
263           @}
264         ;
265
266 Multerm:
267           '*' Term Multerm
268           @{
269             @i @Multerm.node@ = TREENULL;
270           @}
271
272         | '*' Term
273           @{
274             @i @Multerm.node@ = TREENULL;
275           @}
276         ;
277
278 Orterm:
279           OR Term Orterm
280           @{
281             @i @Orterm.node@ = TREENULL;
282           @}
283         | OR Term
284           @{
285             @i @Orterm.node@ = TREENULL;
286           @}
287
288         ;
289
290 Term:
291           '(' Expr ')'
292           @{
293             @i @Term.node@ = @Expr.node@;
294                 @i @Term.exprcount@ = @Expr.exprcount@ + 1; fprintf(stderr, "(Term)- ( Expr )\n");
295           @}
296
297         | NUM
298           @{
299                 @i @Term.exprcount@ = 1; fprintf(stderr, "(Term)- NUM\n");
300             @i @Term.node@ = new_number(@NUM.val@, @Term.exprcount@);
301                 @i @Term.imm@ = 1;
302           @}
303
304         | '-' NUM
305           @{
306                 @i @Term.exprcount@ = 1; fprintf(stderr, "(Term)- - NUM\n");
307             @i @Term.node@ = new_number(-1 * (@NUM.val@), @Term.exprcount@);
308                 @i @Term.imm@ = 1;
309           @}
310
311         | THIS
312           @{
313                 @i @Term.exprcount@ = 1; fprintf(stderr, "(Term)- THIS\n");
314             @i @Term.node@ = new_param(O_ID, strdup("this"), TREENULL, TREENULL, 0, @Term.exprcount@);
315                 @i @Term.imm@ = 0;
316           @}
317
318         | IDENT
319           @{
320             @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM);
321                 @i @Term.exprcount@ = 1; fprintf(stderr, "(Term)- IDENT\n");
322             @i @Term.node@ = new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, tab_lookup(@Term.s@, @IDENT.name@, S_PARM) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_PARM)->param_index, @Term.exprcount@);
323                 @i @Term.imm@ = 0;
324           @}
325
326         | Feld
327           @{
328             @i @Term.node@ = TREENULL;
329                 @i @Term.imm@ = 0;
330                 /*TODO*/@i @Term.exprcount@ = 1;
331           @}
332
333         | IDENT '(' Exprs ')'
334           @{
335             @i @Term.node@ = TREENULL;
336                 @i @Term.imm@ = 0;
337                 /*TODO*/@i @Term.exprcount@ = 1;
338           @}
339
340         | Term '.' IDENT '(' Exprs ')'
341           @{
342             @i @Term.node@ = TREENULL;
343                 @i @Term.imm@ = 0;
344                 /*TODO*/@i @Term.exprcount@ = 1;
345           @}
346
347         ;
348
349 Exprs:
350           Expr ',' Exprs
351         | Expr
352         |
353         ;
354 %%
355
356 extern int yylex();
357 extern int yylineno;
358
359 int yyerror(char *error_text)
360 {
361         fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
362         exit(2);
363 }
364
365 int main(int argc, char **argv)
366 {
367         #if 0
368         yydebug=1;
369         #endif
370         yyparse();
371         return 0;
372 }
373