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