codea: this passt jetzt auch
[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
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; } Lexpr Expr Minusterm Multerm Orterm Term Feld
33 @attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement
34
35 @traversal @postorder c
36 @traversal @preorder reg
37 @traversal @postorder gen
38
39 %%
40 Input:
41           Program
42           @{
43             @i @Program.f@ = tab_new();
44             @gen @revorder(1) printf("\t.text\n");
45           @}
46         ;
47
48 Program:
49           Methoddef ';' Program
50           @{
51             @i @Methoddef.s@ = @Program.0.f@;
52             @i @Program.1.f@ = @Program.0.f@;
53           @}
54
55         | Structdef ';' Program
56           @{
57             @i @Program.1.f@ = tab_merge(@Program.0.f@, @Structdef.f@, 1);
58           @}
59         |
60         ;
61
62 Methoddef:
63           METHOD IDENT '(' Parms ')' Statseq END
64           @{
65             @i @Parms.parms@ = 1;
66             @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
67             @gen @revorder(1) func_header(@IDENT.name@);
68           @}
69         ;
70
71 Structdef:
72           STRUCT FeldID END
73           @{
74             @i @Structdef.f@ = @FeldID.f@;
75           @}
76         ;
77
78 Parms:
79           /* lokale Vars werden in Statement in die tabelle eingefuegt */
80           IDENT Parms
81           @{
82             @i @Parms.1.parms@ = @Parms.parms@ + 1;
83             @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_PARM, 1, @Parms.parms@);
84           @}
85
86         |
87           @{
88             @i @Parms.f@ = tab_new();
89           @}
90         ;
91
92 FeldID:
93           IDENT FeldID
94           @{
95             @i @FeldID.0.f@ = tab_add_symbol(@FeldID.1.f@, @IDENT.name@, S_FIELD, 1, -1);
96           @}
97
98         |
99           @{
100             @i @FeldID.f@ = tab_new();
101           @}
102         ;
103
104 Statseq:
105           Statement ';' Statseq
106           @{
107                 @i @Statement.sin@ = @Statseq.0.s@;
108                 @i @Statseq.1.s@ = @Statement.sout@;
109                 @gen burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1);
110           @}
111
112         |
113         ;
114
115 Statement:
116           Lexpr ASSIGN Expr
117           @{
118                 statinout()
119                 xxputsin(@Lexpr.s@,)
120                 xxputsin(@Expr.s@,)
121             @i @Statement.node@ = TREENULL;
122           @}
123
124         | VAR IDENT ASSIGN Expr
125           @{
126                 /* tab_clone ist hier noetig, vgl. folgendes statement
127                  * > var x := x - 1; */
128                 @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1, -1);
129                 xxputsin(@Expr.s@,)
130             @i @Statement.node@ = TREENULL;
131           @}
132
133         | Expr
134           @{
135                 statinout()
136                 xxputsin(@Expr.s@,)
137             @i @Statement.node@ = TREENULL;
138           @}
139
140         | IF Expr THEN Statseq END
141           @{
142                 statinout()
143                 xxputsin(@Expr.s@,)
144                 xxputsin(@Statseq.s@,)
145             @i @Statement.node@ = TREENULL;
146           @}
147
148         | IF Expr THEN Statseq ELSE Statseq END
149           @{
150                 statinout()
151                 xxputsin(@Expr.s@,)
152                 xxputsin(@Statseq.0.s@,)
153                 xxputsin(@Statseq.1.s@,)
154             @i @Statement.node@ = TREENULL;
155           @}
156
157         | WHILE Expr DO Statseq END
158           @{
159                 statinout()
160                 xxputsin(@Expr.s@,)
161                 xxputsin(@Statseq.s@,)
162             @i @Statement.node@ = TREENULL;
163           @}
164
165         | RETURN Expr
166           @{
167                 statinout()
168                 xxputsin(@Expr.s@,)
169                 @i @Statement.node@ = new_node(O_RET, @Expr.node@, TREENULL);
170                 @reg @Statement.node@->reg = next_reg((char *)NULL, 0); @Expr.node@->reg = @Statement.node@->reg;
171           @}
172         ;
173
174 Lexpr:
175           IDENT
176           @{
177             @i @Lexpr.node@ = TREENULL;
178             @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM);
179           @}
180
181         | Feld
182         ;
183
184 Feld: Term '.' IDENT
185           @{
186             @c check(@Feld.s@, @IDENT.name@, S_FIELD);
187             @i @Feld.node@ = TREENULL;
188                 @reg fprintf(stderr, "w00t8\n");
189           @}
190         ;
191
192 Expr:
193           Term
194           @{
195             @reg @Term.node@->reg = @Expr.node@->reg;
196           @}
197
198         | NOT Term
199           @{
200             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t2\n");
201           @}
202
203         | Term Minusterm
204           @{
205             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t3\n");
206           @}
207
208         | Term Multerm
209           @{
210             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t4\n");
211           @}
212
213         | Term Orterm
214           @{
215             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t5\n");
216           @}
217
218         | Term '<' Term
219           @{
220             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t6\n");
221           @}
222
223         | Term '=' Term
224           @{
225             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t7\n");
226           @}
227         ;
228
229 Minusterm:
230           '-' Term Minusterm
231           @{
232             @i @Minusterm.node@ = TREENULL;
233             @reg fprintf(stderr, "minus1\n");
234           @}
235
236         | '-' Term
237           @{
238             @i @Minusterm.node@ = TREENULL;
239             @reg fprintf(stderr, "minus2\n");
240           @}
241         ;
242
243 Multerm:
244           '*' Term Multerm
245           @{
246             @i @Multerm.node@ = TREENULL;
247             @reg fprintf(stderr, "mul1\n");
248           @}
249
250         | '*' Term
251           @{
252             @i @Multerm.node@ = TREENULL;
253             @reg fprintf(stderr, "mul2\n");
254           @}
255         ;
256
257 Orterm:
258           OR Term Orterm
259           @{
260             @i @Orterm.node@ = TREENULL;
261             @reg fprintf(stderr, "or1\n");
262           @}
263         | OR Term
264           @{
265             @i @Orterm.node@ = TREENULL;
266             @reg fprintf(stderr, "or2\n");
267           @}
268
269         ;
270
271 Term:
272           '(' Expr ')'
273           @{
274             @i @Term.node@ = TREENULL;
275             @reg fprintf(stderr, "wtf1\n");
276           @}
277
278         | NUM
279           @{
280             @i @Term.node@ = TREENULL;
281             @reg fprintf(stderr, "wtf2\n");
282           @}
283
284         | '-' NUM
285           @{
286             @i @Term.node@ = TREENULL;
287             @reg fprintf(stderr, "wtf3\n");
288           @}
289
290         | THIS
291           @{
292             @i @Term.node@ = new_node(O_ID, TREENULL, TREENULL); @Term.node@->param_index = 0;
293             @reg fprintf(stderr, "wtf4\n");
294           @}
295
296         | IDENT
297           @{
298             @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM);
299             @i @Term.node@ = new_node(O_ID, TREENULL, TREENULL); {
300                         struct symbol *tmp;
301                         if((tmp = tab_lookup(@Term.s@, @IDENT.name@, S_PARM)) != TREENULL) {
302                                 @Term.node@->param_index = tmp->param_index;
303                         }
304                 }
305             @reg fprintf(stderr, "wtf5\n");
306           @}
307
308         | Feld
309           @{
310             @i @Term.node@ = TREENULL;
311             @reg fprintf(stderr, "wtf6\n");
312           @}
313
314         | IDENT '(' Exprs ')'
315           @{
316             @i @Term.node@ = TREENULL;
317             @reg fprintf(stderr, "wtf7\n");
318           @}
319
320         | Term '.' IDENT '(' Exprs ')'
321           @{
322             @i @Term.node@ = TREENULL;
323             @reg fprintf(stderr, "wtf8\n");
324           @}
325
326         ;
327
328 Exprs:
329           Expr ',' Exprs
330         | Expr
331         |
332         ;
333 %%
334
335 extern int yylex();
336 extern int yylineno;
337
338 int yyerror(char *error_text)
339 {
340         fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
341         exit(2);
342 }
343
344 int main(int argc, char **argv)
345 {
346         #if 0
347         yydebug=1;
348         #endif
349         yyparse();
350         return 0;
351 }
352