%{
#include <stdio.h>
#include <stdlib.h>
+ #include <string.h>
+ #include "symtable.h"
%}
-%start Program
-%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS
-%token IDENT NUM
+%start Input
+%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS IDENT NUM ASSIGN
+
+@macro xxputsin(xx,)
+ @i xx = @Statement.sin@;
+@end
+
+@macro statinout()
+ @i @Statement.sout@ = @Statement.sin@;
+ /* das
+ *> xxputsin(@Statement.sout@,)
+ * geht nicht, weil verschachtelte macros deaktiviert sind */
+@end
+
+@autoinh s
+@attributes { char *name; } IDENT
+@attributes { struct symbol *f; } FeldID Parms Structdef Program
+@attributes { struct symbol *s; } Methoddef Statseq Lexpr Expr Minusterm Multerm Orterm Term Exprs Feld
+@attributes { struct symbol *sin; struct symbol *sout; } Statement
+
+@traversal @postorder c
%%
+Input:
+ Program
+ @{
+ @i @Program.f@ = tab_new();
+ @}
+ ;
Program:
Methoddef ';' Program
+ @{
+ @i @Methoddef.s@ = @Program.0.f@;
+ @i @Program.1.f@ = @Program.0.f@;
+ @}
+
| Structdef ';' Program
+ @{
+ @i @Program.1.f@ = tab_merge(@Program.0.f@, @Structdef.f@, 1);
+ @}
|
;
+Methoddef:
+ METHOD IDENT '(' Parms ')' Statseq END
+ @{
+ @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
+ @}
+ ;
+
Structdef:
- STRUCT Idents END
+ STRUCT FeldID END
+ @{
+ @i @Structdef.f@ = @FeldID.f@;
+ @}
;
-Methoddef:
- METHOD IDENT '(' Idents ')' Statseq END
+Parms:
+ /* lokale Vars werden in Statement in die tabelle eingefuegt */
+ IDENT Parms
+ @{
+ @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_VAR, 1);
+ @}
+
+ |
+ @{
+ @i @Parms.f@ = tab_new();
+ @}
;
-Idents:
- IDENT Idents
+FeldID:
+ IDENT FeldID
+ @{
+ @i @FeldID.0.f@ = tab_add_symbol(@FeldID.1.f@, @IDENT.name@, S_FIELD, 1);
+ @}
+
|
+ @{
+ @i @FeldID.f@ = tab_new();
+ @}
;
Statseq:
Statement ';' Statseq
+ @{
+ @i @Statement.sin@ = @Statseq.0.s@;
+ @i @Statseq.1.s@ = @Statement.sout@;
+ @}
+
|
;
Statement:
- Lexpr ':=' Expr
- | VAR IDENT ':=' Expr
+ Lexpr ASSIGN Expr
+ @{
+ statinout()
+ xxputsin(@Lexpr.s@,)
+ xxputsin(@Expr.s@,)
+ @}
+
+ | VAR IDENT ASSIGN Expr
+ @{
+ /* tab_clone ist hier noetig, vgl. folgendes statement
+ * > var x := x - 1; */
+ @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1);
+ xxputsin(@Expr.s@,)
+ @}
+
| Expr
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ @}
+
| IF Expr THEN Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
+ @}
+
| IF Expr THEN Statseq ELSE Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.0.s@,)
+ xxputsin(@Statseq.1.s@,)
+ @}
+
| WHILE Expr DO Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
+ @}
+
| RETURN Expr
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ @}
;
Lexpr:
IDENT
- | Term '.' IDENT
+ @{
+ @c check(@Lexpr.s@, @IDENT.name@, S_VAR);
+ @}
+
+ | Feld
+ ;
+
+Feld: Term '.' IDENT
+ @{
+ @c check(@Feld.s@, @IDENT.name@, S_FIELD);
+ @}
;
Expr:
| OR Term
;
-
Term:
'(' Expr ')'
| NUM
| '-' NUM
| THIS
| IDENT
- | Term '.' IDENT
+ @{
+ @c check(@Term.s@, @IDENT.name@, S_VAR);
+ @}
+
+ | Feld
| IDENT '(' Exprs ')'
| Term '.' IDENT '(' Exprs ')'
;
-/* beachte dass hier auch "nichts" vorkommen kann
- * sonst waer ein aufruf der art 'f()' nicht
- * moeglich (leere parameterliste) */
Exprs:
+ Expr ',' Exprs
| Expr
- | Exprs ',' Expr
+ |
;
-
%%
extern int yylex();
int yyerror(char *error_text)
{
- fprintf(stderr,"Line %i: %s\n", yylineno, error_text);
+ fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
exit(2);
}