%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS
%token IDENT NUM ASSIGN
-/* TODO: macro, see oxURM.ps @ p. 25 */
+@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
/* f .. fields
* s .. symbols */
@attributes { char *name; } IDENT
@attributes { struct symbol *f; struct symbol *s; } Program
-@attributes { struct symbol *f; } Idents Structdef
-@attributes { struct symbol *p; } Parms
+@attributes { struct symbol *f; } Idents Structdef Parms
@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.0.f@ = new_tab();
@}
-
;
Methoddef:
METHOD IDENT '(' Parms ')' Statseq END
@{
- @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.p@, 0);
+ @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
@}
-
;
Structdef:
@{
@i @Structdef.f@ = @Idents.f@;
@}
-
;
Parms:
/* lokale Vars werden in Statement in die tabelle eingefuegt */
IDENT Parms
@{
- @i @Parms.0.p@ = tab_add_symbol(@Parms.1.p@, @IDENT.name@, S_VAR, 1);
+ @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_VAR, 1);
@}
|
@{
- @i @Parms.p@ = new_tab();
+ @i @Parms.f@ = new_tab();
@}
-
;
Idents:
@{
@i @Idents.f@ = new_tab();
@}
-
;
Statseq:
@}
|
-
;
Statement:
Lexpr ASSIGN Expr
@{
- @i @Statement.sout@ = @Statement.sin@;
- @i @Lexpr.s@ = @Statement.sin@;
- @i @Expr.s@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Lexpr.s@,)
+ xxputsin(@Expr.s@,)
@}
| VAR IDENT ASSIGN Expr
@{
@i @Statement.sout@ = tab_add_symbol(clone_tab(@Statement.sin@), @IDENT.name@, S_VAR, 1);
- @i @Expr.s@ = @Statement.sin@;
+ xxputsin(@Expr.s@,)
@}
| Expr
@{
- @i @Expr.s@ = @Statement.sin@;
- @i @Statement.sout@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Expr.s@,)
@}
| IF Expr THEN Statseq END
@{
- @i @Expr.s@ = @Statement.sin@;
- @i @Statseq.s@ = @Statement.sin@;
- @i @Statement.sout@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
@}
| IF Expr THEN Statseq ELSE Statseq END
@{
- @i @Expr.s@ = @Statement.sin@;
- @i @Statseq.0.s@ = @Statement.sin@;
- @i @Statseq.1.s@ = @Statement.sin@;
- @i @Statement.sout@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.0.s@,)
+ xxputsin(@Statseq.1.s@,)
@}
| WHILE Expr DO Statseq END
@{
- @i @Expr.s@ = @Statement.sin@;
- @i @Statseq.s@ = @Statement.sin@;
- @i @Statement.sout@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
@}
| RETURN Expr
@{
- @i @Expr.s@ = @Statement.sin@;
- @i @Statement.sout@ = @Statement.sin@;
+ statinout()
+ xxputsin(@Expr.s@,)
@}
-
;
Lexpr:
@{
@c check_field(@Feld.s@, @IDENT.name@);
@}
-
;
Expr:
| OR Term
;
-
Term:
'(' Expr ')'
| NUM
@{
@c check_variable(@Term.s@, @IDENT.name@);
@}
-
;
/* beachte dass hier auch "nichts" vorkommen kann
| Expr
| Exprs ',' Expr
;
-
%%
extern int yylex();