7634069298681de8a634b4c1b3dc7519515a2d41
[uebersetzerbau-ss10.git] / ag / parser.y
1 %{
2         #include <stdio.h>
3         #include <stdlib.h>
4         #include <string.h>
5         #include "symbol_table.h"
6 %}
7
8 %start          Input
9 %token          FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT
10 %token          ID NUM ASSIGN GREATER
11
12 @autoinh symbols
13
14 @attributes     { char *name; } ID
15 @attributes     { struct symbol_t *fields; struct symbol_t *symbols; } Program
16 @attributes     { struct symbol_t *fields; } Ids Structdef
17 @attributes     { struct symbol_t *pars; } Pars
18 @attributes     { struct symbol_t *symbols; } Funcdef Stats Bool Expr Call Lexpr Field Term Plusterm Malterm Bterm Orterm Exprs
19 @attributes     { struct symbol_t *in_symbols; struct symbol_t *out_symbols; } Stat
20
21 @traversal @postorder t
22
23 %%
24
25 Input:            Program
26                 @{ @i @Program.symbols@ = @Program.fields@; @}
27
28                 ;
29
30 Program:          Funcdef ';' Program
31                 @{
32                    @i @Program.fields@ = @Program.1.fields@;
33                 @}
34
35                 | Structdef ';' Program
36                 @{
37                    @i @Program.fields@ = table_merge(@Structdef.fields@, @Program.1.fields@, 1);
38                    @i @Program.1.symbols@ = @Program.0.symbols@;
39                 @}
40
41                 |
42                 @{ @i @Program.fields@ = new_table(); @}
43
44                 ;
45  
46 Funcdef:          FUNC ID '(' Pars ')' Stats END
47                 @{ @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, @Pars.pars@, 0); @}
48
49                 |
50                   FUNC ID '(' ')' Stats END
51                 @{ @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, new_table(), 0); @}
52
53                 ;  
54  
55 Structdef:        STRUCT Ids END
56                 @{ @i @Structdef.fields@ = @Ids.fields@; @}
57
58                 ;  
59
60 Ids:              ID Ids
61                 @{ @i @Ids.fields@ = table_add_symbol(@Ids.1.fields@, @ID.name@, SYMBOL_TYPE_FIELD, 1); @}
62
63                 |
64                 @{ @i @Ids.fields@ = new_table(); @}
65
66                 ;
67
68 Pars:             Pars ',' ID
69                 @{ @i @Pars.pars@ = table_add_symbol(@Pars.1.pars@, @ID.name@, SYMBOL_TYPE_VAR, 0); @}
70
71                 | ID
72                 @{ @i @Pars.pars@ = table_add_symbol(new_table(), @ID.name@, SYMBOL_TYPE_VAR, 0); @}
73
74                 ; 
75  
76 Stats:            Stat ';' Stats
77                 @{
78                    @i @Stat.in_symbols@ = @Stats.symbols@;
79                    @i @Stats.1.symbols@ = @Stat.out_symbols@;
80                 @}
81
82                 |
83                 ;  
84  
85 Stat:             VAR ID ASSIGN Expr
86                 @{
87                    @i @Stat.out_symbols@ = table_add_symbol(clone_table(@Stat.in_symbols@), @ID.name@, SYMBOL_TYPE_VAR, 0);
88                    @i @Expr.symbols@ = @Stat.in_symbols@;
89                 @}
90
91                 | Lexpr ASSIGN Expr
92                 @{
93                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
94                    @i @Lexpr.symbols@ = @Stat.in_symbols@;
95                    @i @Expr.symbols@ = @Stat.in_symbols@;
96                 @}
97
98                 | IF Bool THEN Stats END
99                 @{
100                    @i @Bool.symbols@ = @Stat.in_symbols@;
101                    @i @Stats.symbols@ = @Stat.in_symbols@;
102                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
103                 @}
104
105                 | IF Bool THEN Stats ELSE Stats END
106                 @{
107                    @i @Bool.symbols@ = @Stat.in_symbols@;
108                    @i @Stats.symbols@ = @Stat.in_symbols@;
109                    @i @Stats.1.symbols@ = @Stat.in_symbols@;
110                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
111                 @}
112
113                 | WHILE Bool DO Stats END
114                 @{
115                    @i @Bool.symbols@ = @Stat.in_symbols@;
116                    @i @Stats.symbols@ = @Stat.in_symbols@;
117                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
118                 @}
119
120                 | Call
121                 @{
122                    @i @Call.symbols@ = @Stat.in_symbols@;
123                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
124                 @}
125
126                 | RETURN Expr
127                 @{
128                    @i @Expr.symbols@ = @Stat.in_symbols@;
129                    @i @Stat.out_symbols@ = @Stat.in_symbols@;
130                 @}
131
132                 ;
133  
134 Lexpr:            ID
135                 @{ @t check_variable(@Lexpr.symbols@, @ID.name@); @}
136
137                 | Field
138                 ;
139  
140 Expr:             '-' Term
141                 | Term
142                 | Term Plusterm
143                 | Term Malterm
144                 ;
145
146 Plusterm:         '+' Term Plusterm
147                 | '+' Term
148                 ;
149
150 Malterm:          '*' Term Malterm
151                 | '*' Term
152                 ;
153  
154 Term:             '(' Expr ')'
155                 | ID
156                 @{ @t check_variable(@Term.symbols@, @ID.name@); @}
157
158                 | NUM
159                 | Call
160                 | Field
161                 ;
162
163 Bool:             Bterm
164                 | Bterm Orterm
165                 | NOT Bterm
166                 ;
167
168 Orterm:           OR Bterm Orterm
169                 | OR Bterm
170                 ;
171
172 Bterm:            Term GREATER Term
173                 | Term '=' Term
174                 | '(' Bool ')'
175                 ;
176
177 Field:            Term '.' ID
178                 @{ @t check_field(@Field.symbols@, @ID.name@); @}
179
180                 ;
181
182 Call:             ID '(' Exprs ')'
183                 | ID '(' ')'
184                 ;
185
186 Exprs:            Expr
187                 | Exprs ',' Expr
188                 ;
189
190 %%
191
192 extern int yylex();
193 extern int yylineno;
194
195 int yyerror(char *error_text) {
196         fprintf(stderr,"Line %i: %s\n",yylineno, error_text);
197         exit(2);
198 }
199
200 int main(int argc, char **argv) {
201         yyparse();
202         return 0;
203 }
204