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