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