#include <stdio.h>
#include <stdlib.h>
#include <string.h>
- #include "symbol_table.h"
+ #include "symtable.h"
%}
-%start Input
-%token FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT
-%token ID NUM ASSIGN GREATER
+%start Input
+%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS
+%token IDENT NUM ASSIGN
-@autoinh symbols
+/* TODO: macro, see oxURM.ps @ p. 25 */
-@attributes { char *name; } ID
-@attributes { struct symbol *fields; struct symbol *symbols; } Program
-@attributes { struct symbol *fields; } Ids Structdef
-@attributes { struct symbol *pars; } Pars
-@attributes { struct symbol *symbols; } Funcdef Stats Bool Expr Call Lexpr Field Term Plusterm Malterm Bterm Orterm Exprs
-@attributes { struct symbol *in_symbols; struct symbol *out_symbols; } Stat
+@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 *s; } Methoddef Statseq Lexpr Expr Minusterm Multerm Orterm
+Term Exprs
+@attributes { struct symbol *sin; struct symbol *sout; } Statement
-@traversal @postorder t
+@traversal @postorder c
%%
-Input: Program
- @{ @i @Program.symbols@ = @Program.fields@; @}
-
- ;
-
-Program: Funcdef ';' Program
- @{
- @i @Program.fields@ = @Program.1.fields@;
- @}
-
- | Structdef ';' Program
- @{
- @i @Program.fields@ = tab_merge(@Structdef.fields@, @Program.1.fields@, 1);
- @i @Program.1.symbols@ = @Program.0.symbols@;
- @}
-
- |
- @{ @i @Program.fields@ = new_tab(); @}
-
- ;
-
-Funcdef: FUNC ID '(' Pars ')' Stats END
- @{ @i @Stats.symbols@ = tab_merge(@Funcdef.symbols@, @Pars.pars@, 0); @}
-
- |
- FUNC ID '(' ')' Stats END
- @{ @i @Stats.symbols@ = tab_merge(@Funcdef.symbols@, new_tab(), 0); @}
-
- ;
-
-Structdef: STRUCT Ids END
- @{ @i @Structdef.fields@ = @Ids.fields@; @}
-
- ;
-
-Ids: ID Ids
- @{ @i @Ids.fields@ = tab_add_symbol(@Ids.1.fields@, @ID.name@, S_FIELD, 1); @}
-
- |
- @{ @i @Ids.fields@ = new_tab(); @}
-
- ;
-
-Pars: Pars ',' ID
- @{ @i @Pars.pars@ = tab_add_symbol(@Pars.1.pars@, @ID.name@, S_VAR, 0); @}
-
- | ID
- @{ @i @Pars.pars@ = tab_add_symbol(new_tab(), @ID.name@, S_VAR, 0); @}
-
- ;
-
-Stats: Stat ';' Stats
- @{
- @i @Stat.in_symbols@ = @Stats.symbols@;
- @i @Stats.1.symbols@ = @Stat.out_symbols@;
- @}
-
- |
- ;
-
-Stat: VAR ID ASSIGN Expr
- @{
- @i @Stat.out_symbols@ = tab_add_symbol(clone_tab(@Stat.in_symbols@), @ID.name@, S_VAR, 0);
- @i @Expr.symbols@ = @Stat.in_symbols@;
- @}
-
- | Lexpr ASSIGN Expr
- @{
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @i @Lexpr.symbols@ = @Stat.in_symbols@;
- @i @Expr.symbols@ = @Stat.in_symbols@;
- @}
-
- | IF Bool THEN Stats END
- @{
- @i @Bool.symbols@ = @Stat.in_symbols@;
- @i @Stats.symbols@ = @Stat.in_symbols@;
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @}
-
- | IF Bool THEN Stats ELSE Stats END
- @{
- @i @Bool.symbols@ = @Stat.in_symbols@;
- @i @Stats.symbols@ = @Stat.in_symbols@;
- @i @Stats.1.symbols@ = @Stat.in_symbols@;
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @}
-
- | WHILE Bool DO Stats END
- @{
- @i @Bool.symbols@ = @Stat.in_symbols@;
- @i @Stats.symbols@ = @Stat.in_symbols@;
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @}
-
- | Call
- @{
- @i @Call.symbols@ = @Stat.in_symbols@;
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @}
-
- | RETURN Expr
- @{
- @i @Expr.symbols@ = @Stat.in_symbols@;
- @i @Stat.out_symbols@ = @Stat.in_symbols@;
- @}
-
- ;
-
-Lexpr: ID
- @{ @t check_variable(@Lexpr.symbols@, @ID.name@); @}
-
- | Field
- ;
-
-Expr: '-' Term
- | Term
- | Term Plusterm
- | Term Malterm
- ;
-
-Plusterm: '+' Term Plusterm
- | '+' Term
- ;
-
-Malterm: '*' Term Malterm
- | '*' Term
- ;
-
-Term: '(' Expr ')'
- | ID
- @{ @t check_variable(@Term.symbols@, @ID.name@); @}
-
- | NUM
- | Call
- | Field
- ;
-
-Bool: Bterm
- | Bterm Orterm
- | NOT Bterm
- ;
-
-Orterm: OR Bterm Orterm
- | OR Bterm
- ;
-
-Bterm: Term GREATER Term
- | Term '=' Term
- | '(' Bool ')'
- ;
-
-Field: Term '.' ID
- @{ @t check_field(@Field.symbols@, @ID.name@); @}
-
- ;
-
-Call: ID '(' Exprs ')'
- | ID '(' ')'
- ;
-
-Exprs: Expr
- | Exprs ',' Expr
- ;
+Input:
+ Program
+ @{
+ @i @Program.s@ = @Program.f@;
+ @}
+ ;
+
+Program:
+ Methoddef ';' Program
+ @{
+ @i @Program.0.f@ = @Program.1.f@;
+ @}
+
+ | Structdef ';' Program
+ @{
+ @i @Program.0.f@ = tab_merge(@Structdef.f@, @Program.1.f@, 1);
+ @}
+
+ |
+ @{
+ @i @Program.0.f@ = new_tab();
+ @}
+
+ ;
+
+Methoddef:
+ METHOD IDENT '(' Parms ')' Statseq END
+ @{
+ @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.p@, 0);
+ @}
+
+ ;
+
+Structdef:
+ STRUCT Idents END
+ @{
+ @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.p@ = new_tab();
+ @}
+
+ ;
+
+Idents:
+ IDENT Idents
+ @{
+ @i @Idents.0.f@ = tab_add_symbol(@Idents.1.f@, @IDENT.name@, S_FIELD, 1);
+ @}
+
+ |
+ @{
+ @i @Idents.f@ = new_tab();
+ @}
+
+ ;
+
+Statseq:
+ Statement ';' Statseq
+ @{
+ @i @Statement.sin@ = @Statseq.0.s@;
+ @i @Statseq.1.s@ = @Statement.sout@;
+ @}
+
+ |
+
+ ;
+
+Statement:
+ Lexpr ASSIGN Expr
+ @{
+ @i @Statement.sout@ = @Statement.sin@;
+ @i @Lexpr.s@ = @Statement.sin@;
+ @i @Expr.s@ = @Statement.sin@;
+ @}
+
+ | VAR IDENT ASSIGN Expr
+ @{
+ @i @Statement.sout@ = tab_add_symbol(clone_tab(@Statement.sin@), @IDENT.name@, S_VAR, 0);
+ @i @Expr.s@ = @Statement.sin@;
+ @}
+
+ | Expr
+ @{
+ @i @Expr.s@ = @Statement.sin@;
+ @i @Statement.sout@ = @Statement.sin@;
+ @}
+
+ | IF Expr THEN Statseq END
+ @{
+ @i @Expr.s@ = @Statement.sin@;
+ @i @Statseq.s@ = @Statement.sin@;
+ @i @Statement.sout@ = @Statement.sin@;
+ @}
+
+ | 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@;
+ @}
+
+ | WHILE Expr DO Statseq END
+ @{
+ @i @Expr.s@ = @Statement.sin@;
+ @i @Statseq.s@ = @Statement.sin@;
+ @i @Statement.sout@ = @Statement.sin@;
+ @}
+
+ | RETURN Expr
+ @{
+ @i @Expr.s@ = @Statement.sin@;
+ @i @Statement.sout@ = @Statement.sin@;
+ @}
+
+ ;
+
+Lexpr:
+ IDENT
+ @{
+ @c check_variable(@Lexpr.s@, @IDENT.name@);
+ @}
+
+ | Term '.' IDENT
+ @{
+ @c check_variable(@Lexpr.s@, @IDENT.name@);
+ @}
+
+ ;
+
+Expr:
+ Term
+ | NOT Term
+ | Term Minusterm
+ | Term Multerm
+ | Term Orterm
+ | Term '<' Term
+ | Term '=' Term
+ ;
+
+Minusterm:
+ '-' Term Minusterm
+ | '-' Term
+ ;
+
+Multerm:
+ '*' Term Multerm
+ | '*' Term
+ ;
+
+Orterm:
+ OR Term Orterm
+ | OR Term
+ ;
+
+
+Term:
+ '(' Expr ')'
+ | NUM
+ | '-' NUM
+ | THIS
+ | IDENT
+ @{
+ @c check_variable(@Term.s@, @IDENT.name@);
+ @}
+
+ | Term '.' IDENT
+ @{
+ @c check_variable(@Term.s@, @IDENT.name@);
+ @}
+
+ | IDENT '(' Exprs ')'
+ @{
+ @c check_variable(@Term.s@, @IDENT.name@);
+ @}
+
+ | Term '.' IDENT '(' Exprs ')'
+ @{
+ @c check_variable(@Term.s@, @IDENT.name@);
+ @}
+
+ ;
+
+/* beachte dass hier auch "nichts" vorkommen kann
+ * sonst waer ein aufruf der art 'f()' nicht
+ * moeglich (leere parameterliste) */
+Exprs:
+ | Expr
+ | Exprs ',' Expr
+ ;
%%
extern int yylex();
extern int yylineno;
-int yyerror(char *error_text) {
- fprintf(stderr,"Line %i: %s\n",yylineno, error_text);
+int yyerror(char *error_text)
+{
+ fprintf(stderr,"Line %i: %s\n", yylineno, error_text);
exit(2);
}
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
+ #if 0
+ yydebug=1;
+ #endif
yyparse();
return 0;
}