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