ag: fuer ub10 angabe angepasst. mal testfaelle schreiben ;)
authorBernhard Urban <lewurm@gmail.com>
Tue, 30 Mar 2010 14:18:41 +0000 (16:18 +0200)
committerBernhard Urban <lewurm@gmail.com>
Tue, 30 Mar 2010 15:30:56 +0000 (17:30 +0200)
ag/Makefile
ag/parser.y
ag/scanner.lex

index d4eff747f76f2944b8e14a53731d2712a38dcd0e..9b6ac4564ce1f3bb665eb82bb63b00e78780aa7c 100644 (file)
@@ -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
 
index 181bc5a0a9ffb6fb38474568b055587075fa3ade..3fe648bd80566301f325261c311d752afc42cf48 100644 (file)
 %{
        #include <stdio.h>
        #include <stdlib.h>
+       #include <string.h>
+       #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
index 049cdd2c1e54245ce7aad3a3f12b63dd65da5130..c104d0fc7d822d8e45f03841a7edbc8eef882d30 100644 (file)
@@ -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 */