3fe648bd80566301f325261c311d752afc42cf48
[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
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         | Term '.' IDENT
165           @{
166                 @c check_variable(@Lexpr.s@, @IDENT.name@);
167           @}
168
169         ;
170
171 Expr:
172           Term
173         | NOT Term
174         | Term Minusterm
175         | Term Multerm
176         | Term Orterm
177         | Term '<' Term
178         | Term '=' Term
179         ;
180
181 Minusterm:
182           '-' Term Minusterm
183         | '-' Term
184         ;
185
186 Multerm:
187           '*' Term Multerm
188         | '*' Term
189         ;
190
191 Orterm:
192           OR Term Orterm
193         | OR Term
194         ;
195
196
197 Term:
198           '(' Expr ')'
199         | NUM
200         | '-' NUM
201         | THIS
202         | IDENT
203           @{
204                 @c check_variable(@Term.s@, @IDENT.name@);
205           @}
206
207         | Term '.' IDENT
208           @{
209                 @c check_variable(@Term.s@, @IDENT.name@);
210           @}
211
212         | IDENT '(' Exprs ')'
213           @{
214                 @c check_variable(@Term.s@, @IDENT.name@);
215           @}
216
217         | Term '.' IDENT '(' Exprs ')'
218           @{
219                 @c check_variable(@Term.s@, @IDENT.name@);
220           @}
221
222         ;
223
224 /* beachte dass hier auch "nichts" vorkommen kann
225  * sonst waer ein aufruf der art 'f()' nicht
226  * moeglich (leere parameterliste) */
227 Exprs:
228         | Expr
229         | Exprs ',' Expr
230         ;
231
232 %%
233
234 extern int yylex();
235 extern int yylineno;
236
237 int yyerror(char *error_text)
238 {
239         fprintf(stderr,"Line %i: %s\n", yylineno, error_text);
240         exit(2);
241 }
242
243 int main(int argc, char **argv)
244 {
245         #if 0
246         yydebug=1;
247         #endif
248         yyparse();
249         return 0;
250 }
251