From 9ad86eed903ac2dc17a54c25ed369fc84255fac8 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 30 Mar 2010 16:18:41 +0200 Subject: [PATCH] ag: fuer ub10 angabe angepasst. mal testfaelle schreiben ;) --- ag/Makefile | 4 +- ag/parser.y | 148 +++++++++++++++++++++++++++++++++++++++++++++++-- ag/scanner.lex | 14 ++++- 3 files changed, 155 insertions(+), 11 deletions(-) diff --git a/ag/Makefile b/ag/Makefile index d4eff74..9b6ac45 100644 --- a/ag/Makefile +++ b/ag/Makefile @@ -7,7 +7,7 @@ TARGETS := parser.y scanner.lex all: $(NAME) $(NAME): $(OBJS) - @echo " LINK $<" + @echo " LINK $@" @gcc -o $@ $(OBJS) -lfl scanner.c: oxout.l @@ -30,7 +30,7 @@ oxout.y oxout.l: $(TARGETS) .PHONY: clean clean: - rm -f $(NAME) $(OBJS) scanner.c parser.{h,c,output} oxout.{y,l} + rm -f $(NAME) $(OBJS) scanner.c parser.{h,c,output} oxout.{y,l,h} 1test: 2test diff --git a/ag/parser.y b/ag/parser.y index 181bc5a..3fe648b 100644 --- a/ag/parser.y +++ b/ag/parser.y @@ -1,51 +1,171 @@ %{ #include #include + #include + #include "symtable.h" %} -%start Program +%start Input %token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS -%token IDENT NUM +%token IDENT NUM ASSIGN + +/* TODO: macro, see oxURM.ps @ p. 25 */ + +@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 c %% +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@; + @} + ; -Methoddef: - METHOD IDENT '(' Idents ')' Statseq END +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 ':=' Expr - | VAR IDENT ':=' Expr + 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: @@ -80,9 +200,25 @@ Term: | '-' 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 diff --git a/ag/scanner.lex b/ag/scanner.lex index 049cdd2..c104d0f 100644 --- a/ag/scanner.lex +++ b/ag/scanner.lex @@ -4,7 +4,6 @@ #include "parser.h" KEYWORD struct|end|method|var|if|then|else|while|do|return|not|or|this -SPECIAL_CHAR \;|\(|\)|\:=|\.|\-|\*|\<|\=|\, IDENTIFIER [a-zA-Z_][0-9a-zA-Z_]* NUMBER_HEX 0x[0-9A-Fa-f]+ NUMBER_DEC [0-9]+ @@ -41,12 +40,21 @@ not return(NOT); or return(OR); this return(THIS); -{IDENTIFIER} return(IDENT); +{IDENTIFIER} return(IDENT); @{ @IDENT.name@ = strdup(yytext); @} {NUMBER_DEC} return(NUM); {NUMBER_HEX} return(NUM); -{SPECIAL_CHAR} return(*yytext); +\:= return(ASSIGN); +\; return(';'); +\( return('('); +\) return(')'); +\. return('.'); +\- return('-'); +\* return('*'); +\< return('<'); +\= return('='); +\, return(','); {WHITESPACE} /* ignore */ -- 2.25.1