ag: felder haben nicht ganz gepasst
[uebersetzerbau-ss10.git] / ag / parser.y
1 %{
2         #include <stdio.h>
3         #include <stdlib.h>
4         #include <string.h>
5         #include "symtable.h"
6 %}
7
8 %start Input
9 %token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS
10 %token IDENT NUM ASSIGN
11
12 /* TODO: macro, see oxURM.ps @ p. 25 */
13
14 @autoinh s
15 /* f .. fields
16  * s .. symbols  */
17 @attributes { char *name; } IDENT
18 @attributes { struct symbol *f; struct symbol *s; } Program
19 @attributes { struct symbol *f; } Idents Structdef
20 @attributes { struct symbol *p; } Parms
21 @attributes { struct symbol *s; } Methoddef Statseq Lexpr Expr Minusterm Multerm Orterm
22 Term Exprs Feld
23 @attributes { struct symbol *sin; struct symbol *sout; } Statement
24
25 @traversal @postorder c
26
27 %%
28
29 Input:
30           Program
31           @{
32                 @i @Program.s@ = @Program.f@;
33           @}
34         ;
35
36 Program:
37           Methoddef ';' Program
38           @{
39             @i @Program.0.f@ = @Program.1.f@;
40           @}
41           
42         | Structdef ';' Program
43           @{
44             @i @Program.0.f@ = tab_merge(@Structdef.f@, @Program.1.f@, 1);
45           @}
46
47         |
48           @{
49                 @i @Program.0.f@ = new_tab();
50           @}
51
52         ;
53
54 Methoddef:
55           METHOD IDENT '(' Parms ')' Statseq END
56           @{
57             @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.p@, 0);
58           @}
59
60         ;
61
62 Structdef:
63           STRUCT Idents END
64           @{
65             @i @Structdef.f@ = @Idents.f@;
66           @}
67
68         ;
69
70 Parms:
71           /* lokale Vars werden in Statement in die tabelle eingefuegt */
72           IDENT Parms
73           @{
74             @i @Parms.0.p@ = tab_add_symbol(@Parms.1.p@, @IDENT.name@, S_VAR, 1);
75           @}
76
77         |
78           @{
79             @i @Parms.p@ = new_tab();
80           @}
81
82         ;
83
84 Idents:
85           IDENT Idents
86           @{
87             @i @Idents.0.f@ = tab_add_symbol(@Idents.1.f@, @IDENT.name@, S_FIELD, 1);
88           @}
89
90         |
91           @{
92             @i @Idents.f@ = new_tab();
93           @}
94
95         ;
96
97 Statseq:
98           Statement ';' Statseq
99           @{
100                 @i @Statement.sin@ = @Statseq.0.s@;
101                 @i @Statseq.1.s@ = @Statement.sout@;
102           @}
103
104         |
105
106         ;
107
108 Statement:
109           Lexpr ASSIGN Expr
110           @{
111                 @i @Statement.sout@ = @Statement.sin@;
112                 @i @Lexpr.s@ = @Statement.sin@;
113                 @i @Expr.s@ = @Statement.sin@;
114           @}
115
116         | VAR IDENT ASSIGN Expr
117           @{
118                 @i @Statement.sout@ = tab_add_symbol(clone_tab(@Statement.sin@), @IDENT.name@, S_VAR, 0);
119                 @i @Expr.s@ = @Statement.sin@;
120           @}
121
122         | Expr
123           @{
124                 @i @Expr.s@ = @Statement.sin@;
125                 @i @Statement.sout@ = @Statement.sin@;
126           @}
127
128         | IF Expr THEN Statseq END
129           @{
130                 @i @Expr.s@ = @Statement.sin@;
131                 @i @Statseq.s@ = @Statement.sin@;
132                 @i @Statement.sout@ = @Statement.sin@;
133           @}
134
135         | IF Expr THEN Statseq ELSE Statseq END
136           @{
137                 @i @Expr.s@ = @Statement.sin@;
138                 @i @Statseq.0.s@ = @Statement.sin@;
139                 @i @Statseq.1.s@ = @Statement.sin@;
140                 @i @Statement.sout@ = @Statement.sin@;
141           @}
142
143         | WHILE Expr DO Statseq END
144           @{
145                 @i @Expr.s@ = @Statement.sin@;
146                 @i @Statseq.s@ = @Statement.sin@;
147                 @i @Statement.sout@ = @Statement.sin@;
148           @}
149
150         | RETURN Expr
151           @{
152                 @i @Expr.s@ = @Statement.sin@;
153                 @i @Statement.sout@ = @Statement.sin@;
154           @}
155
156         ;
157
158 Lexpr:
159           IDENT
160           @{
161                 @c check_variable(@Lexpr.s@, @IDENT.name@);
162           @}
163
164         | Feld
165         ;
166
167 Feld: Term '.' IDENT
168           @{
169                 @c check_field(@Feld.s@, @IDENT.name@);
170           @}
171
172         ;
173
174 Expr:
175           Term
176         | NOT Term
177         | Term Minusterm
178         | Term Multerm
179         | Term Orterm
180         | Term '<' Term
181         | Term '=' Term
182         ;
183
184 Minusterm:
185           '-' Term Minusterm
186         | '-' Term
187         ;
188
189 Multerm:
190           '*' Term Multerm
191         | '*' Term
192         ;
193
194 Orterm:
195           OR Term Orterm
196         | OR Term
197         ;
198
199
200 Term:
201           '(' Expr ')'
202         | NUM
203         | '-' NUM
204         | THIS
205         | IDENT
206           @{
207                 @c check_variable(@Term.s@, @IDENT.name@);
208           @}
209
210         | Feld
211         | IDENT '(' Exprs ')'
212           @{
213                 @c check_variable(@Term.s@, @IDENT.name@);
214           @}
215
216         | Term '.' IDENT '(' Exprs ')'
217           @{
218                 @c check_variable(@Term.s@, @IDENT.name@);
219           @}
220
221         ;
222
223 /* beachte dass hier auch "nichts" vorkommen kann
224  * sonst waer ein aufruf der art 'f()' nicht
225  * moeglich (leere parameterliste) */
226 Exprs:
227         | Expr
228         | Exprs ',' Expr
229         ;
230
231 %%
232
233 extern int yylex();
234 extern int yylineno;
235
236 int yyerror(char *error_text)
237 {
238         fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
239         exit(2);
240 }
241
242 int main(int argc, char **argv)
243 {
244         #if 0
245         yydebug=1;
246         #endif
247         yyparse();
248         return 0;
249 }
250