#include <stdlib.h>
#include <string.h>
#include "symtable.h"
+ #include "chelper.h"
+ #include "tree.h"
%}
%start Input
@end
@autoinh s
+@autosyn node
+
@attributes { char *name; } IDENT
+@attributes { long val; } NUM
@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
+@attributes { struct symbol *s; } Methoddef Statseq Exprs
+@attributes { struct symbol *s; struct treenode *node; } Lexpr Expr Minusterm Multerm Orterm Term Feld
+@attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement
@traversal @postorder c
+@traversal @postorder gen
%%
Input:
Program
@{
@i @Program.f@ = tab_new();
+ @gen @revorder(1) printf("\t.text\n");
@}
;
METHOD IDENT '(' Parms ')' Statseq END
@{
@i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
+ @gen @revorder(1) func_header(@IDENT.name@);
@}
;
/* 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.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_PARM, 1);
@}
|
@{
@i @Statement.sin@ = @Statseq.0.s@;
@i @Statseq.1.s@ = @Statement.sout@;
+ @gen burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1);
@}
|
statinout()
xxputsin(@Lexpr.s@,)
xxputsin(@Expr.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| VAR IDENT ASSIGN Expr
* > var x := x - 1; */
@i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1);
xxputsin(@Expr.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| Expr
@{
statinout()
xxputsin(@Expr.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| IF Expr THEN Statseq END
statinout()
xxputsin(@Expr.s@,)
xxputsin(@Statseq.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| IF Expr THEN Statseq ELSE Statseq END
xxputsin(@Expr.s@,)
xxputsin(@Statseq.0.s@,)
xxputsin(@Statseq.1.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| WHILE Expr DO Statseq END
statinout()
xxputsin(@Expr.s@,)
xxputsin(@Statseq.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| RETURN Expr
@{
statinout()
xxputsin(@Expr.s@,)
+ @i @Statement.node@ = new_node(O_RETURN, @Expr.node@, TREENULL);
@}
;
Lexpr:
IDENT
@{
- @c check(@Lexpr.s@, @IDENT.name@, S_VAR);
+ @i @Lexpr.node@ = TREENULL;
+ @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM);
@}
| Feld
Feld: Term '.' IDENT
@{
@c check(@Feld.s@, @IDENT.name@, S_FIELD);
+ @i @Feld.node@ = TREENULL;
@}
;
Expr:
Term
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| NOT Term
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| Term Minusterm
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| Term Multerm
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| Term Orterm
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| Term '<' Term
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
+
| Term '=' Term
+ @{
+ @i @Expr.node@ = TREENULL;
+ @}
;
Minusterm:
'-' Term Minusterm
+ @{
+ @i @Minusterm.node@ = TREENULL;
+ @}
+
| '-' Term
+ @{
+ @i @Minusterm.node@ = TREENULL;
+ @}
;
Multerm:
'*' Term Multerm
+ @{
+ @i @Multerm.node@ = TREENULL;
+ @}
+
| '*' Term
+ @{
+ @i @Multerm.node@ = TREENULL;
+ @}
;
Orterm:
OR Term Orterm
+ @{
+ @i @Orterm.node@ = TREENULL;
+ @}
| OR Term
+ @{
+ @i @Orterm.node@ = TREENULL;
+ @}
+
;
Term:
'(' Expr ')'
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| NUM
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| '-' NUM
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| THIS
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| IDENT
@{
- @c check(@Term.s@, @IDENT.name@, S_VAR);
+ @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM);
+ @i @Term.node@ = TREENULL;
@}
| Feld
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| IDENT '(' Exprs ')'
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
| Term '.' IDENT '(' Exprs ')'
+ @{
+ @i @Term.node@ = TREENULL;
+ @}
+
;
Exprs: