codea: verschachtelte subtraktionen funktionieren (ohne konstanten)
[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@ = new_node(O_SUB, @Minusterm.node@, @Term.node@);
206
207                 @reg {@Term.node@->reg = @Expr.node@->reg;
208                         @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip);
209                         }
210           @}
211
212         | Term Multerm
213           @{
214             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t4\n");
215           @}
216
217         | Term Orterm
218           @{
219             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t5\n");
220           @}
221
222         | Term '<' Term
223           @{
224             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t6\n");
225           @}
226
227         | Term '=' Term
228           @{
229             @i @Expr.node@ = TREENULL; fprintf(stderr, "w00t7\n");
230           @}
231         ;
232
233 Minusterm:
234           '-' Term Minusterm
235           @{
236             @i @Minusterm.node@ = new_node(O_SUB, @Minusterm.1.node@, @Term.node@);
237
238             @reg { @Minusterm.1.node@->reg = @Minusterm.node@->reg;
239                         @Term.node@->reg = next_reg(@Minusterm.1.node@->reg, @Minusterm.node@->skip);
240                         }
241           @}
242
243         | '-' Term
244           @{
245             @reg @Term.node@->reg = @Minusterm.node@->reg;
246           @}
247         ;
248
249 Multerm:
250           '*' Term Multerm
251           @{
252             @i @Multerm.node@ = TREENULL;
253             @reg fprintf(stderr, "mul1\n");
254           @}
255
256         | '*' Term
257           @{
258             @i @Multerm.node@ = TREENULL;
259             @reg fprintf(stderr, "mul2\n");
260           @}
261         ;
262
263 Orterm:
264           OR Term Orterm
265           @{
266             @i @Orterm.node@ = TREENULL;
267             @reg fprintf(stderr, "or1\n");
268           @}
269         | OR Term
270           @{
271             @i @Orterm.node@ = TREENULL;
272             @reg fprintf(stderr, "or2\n");
273           @}
274
275         ;
276
277 Term:
278           '(' Expr ')'
279           @{
280             @i @Term.node@ = @Expr.node@;
281             @reg fprintf(stderr, "wtf1\n");
282           @}
283
284         | NUM
285           @{
286             @i @Term.node@ = TREENULL;
287             @reg fprintf(stderr, "wtf2\n");
288           @}
289
290         | '-' NUM
291           @{
292             @i @Term.node@ = TREENULL;
293             @reg fprintf(stderr, "wtf3\n");
294           @}
295
296         | THIS
297           @{
298             @i @Term.node@ = new_node(O_ID, TREENULL, TREENULL); @Term.node@->param_index = 0;
299             @reg fprintf(stderr, "wtf4\n");
300           @}
301
302         | IDENT
303           @{
304             @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM);
305             @i @Term.node@ = new_node(O_ID, TREENULL, TREENULL); {
306                         struct symbol *tmp;
307                         if((tmp = tab_lookup(@Term.s@, @IDENT.name@, S_PARM)) != TREENULL) {
308                                 @Term.node@->param_index = tmp->param_index;
309                         }
310                 }
311             @reg fprintf(stderr, "wtf5\n");
312           @}
313
314         | Feld
315           @{
316             @i @Term.node@ = TREENULL;
317             @reg fprintf(stderr, "wtf6\n");
318           @}
319
320         | IDENT '(' Exprs ')'
321           @{
322             @i @Term.node@ = TREENULL;
323             @reg fprintf(stderr, "wtf7\n");
324           @}
325
326         | Term '.' IDENT '(' Exprs ')'
327           @{
328             @i @Term.node@ = TREENULL;
329             @reg fprintf(stderr, "wtf8\n");
330           @}
331
332         ;
333
334 Exprs:
335           Expr ',' Exprs
336         | Expr
337         |
338         ;
339 %%
340
341 extern int yylex();
342 extern int yylineno;
343
344 int yyerror(char *error_text)
345 {
346         fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
347         exit(2);
348 }
349
350 int main(int argc, char **argv)
351 {
352         #if 0
353         yydebug=1;
354         #endif
355         yyparse();
356         return 0;
357 }
358