doc: paulchen beispiele {code{a,b},gesamt} entpackt (jedes mal entpacken nervt langsa...
[uebersetzerbau-ss10.git] / aus_sammelwut / paulchen / ublu / ss08 / abgabe / codea / .svn / text-base / parser.y.svn-base
diff --git a/aus_sammelwut/paulchen/ublu/ss08/abgabe/codea/.svn/text-base/parser.y.svn-base b/aus_sammelwut/paulchen/ublu/ss08/abgabe/codea/.svn/text-base/parser.y.svn-base
new file mode 100644 (file)
index 0000000..869143b
--- /dev/null
@@ -0,0 +1,345 @@
+%{
+       #include <stdio.h>
+       #include <stdlib.h>
+       #include <string.h>
+       #include "symbol_table.h"
+       #include "code_gen.h"
+       #include "tree.h"
+%}
+
+%start         Input
+%token         FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT
+%token         ID NUM ASSIGN GREATER
+
+@autoinh symbols stack_offset all_pars
+@autosyn node defined_vars immediate
+
+@attributes    { char *name; } ID
+@attributes    { long value; } NUM
+@attributes    { struct symbol_t *fields; struct symbol_t *symbols; } Program
+@attributes    { struct symbol_t *fields; } Structdef
+@attributes    { struct symbol_t *fields; int offset; } Ids
+@attributes    { struct symbol_t *pars; int num_pars; int all_pars; } Pars
+@attributes    { struct symbol_t *symbols; int defined_vars; } Funcdef 
+@attributes    { struct symbol_t *symbols; int defined_vars; int stack_offset; } Stats
+@attributes    { struct symbol_t *symbols; treenode *node; int immediate; } Expr Term Plusterm Malterm
+@attributes    { struct symbol_t *symbols; treenode *node; } Bool Call Lexpr Field Bterm Orterm Exprs
+@attributes    { struct symbol_t *in_symbols; struct symbol_t *out_symbols; treenode *node; int defined_vars; int stack_offset; } Stat
+
+@traversal @postorder check
+@traversal @preorder reg
+@traversal @postorder codegen
+
+%%
+
+Input:           Program
+               @{
+                  @i @Program.symbols@ = @Program.fields@;
+
+                  @codegen @revorder(1) printf("\t.text\n");
+               @}
+
+               ;
+
+Program:         Funcdef ';' Program
+               @{
+                  @i @Program.fields@ = @Program.1.fields@;
+               @}
+
+               | Structdef ';' Program
+               @{
+                  @i @Program.fields@ = table_merge(@Structdef.fields@, @Program.1.fields@, 1);
+                  @i @Program.1.symbols@ = @Program.0.symbols@;
+               @}
+
+               |
+               @{ @i @Program.fields@ = new_table(); @}
+
+               ;
+Funcdef:         FUNC ID '(' Pars ')' Stats END
+                       @{
+                  @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, @Pars.pars@, 0);
+                  @i @Stats.stack_offset@ = 0;
+                  @i @Pars.all_pars@ = @Pars.num_pars@;
+
+                  @codegen @revorder(1) function_header(@ID.name@);
+               @}
+
+               | FUNC ID '(' ')' Stats END
+                       @{
+                  @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, new_table(), 0);
+                  @i @Stats.stack_offset@ = 0;
+
+                  @codegen @revorder(1) function_header(@ID.name@);
+               @}
+
+               ;  
+Structdef:       STRUCT Ids END
+               @{
+                  @i @Structdef.fields@ = @Ids.fields@;
+                  @i @Ids.offset@ = 0;
+               @}
+
+               ;  
+
+Ids:             ID Ids
+               @{
+                  @i @Ids.fields@ = table_add_symbol(@Ids.1.fields@, @ID.name@, SYMBOL_TYPE_FIELD, 1, @Ids.offset@);
+                  @i @Ids.1.offset@ = @Ids.offset@ + 1;
+               @}
+
+               |
+               @{ @i @Ids.fields@ = new_table(); @}
+
+               ;
+
+Pars:            Pars ',' ID
+               @{
+                   @i @Pars.pars@ = table_add_symbol(@Pars.1.pars@, @ID.name@, SYMBOL_TYPE_PARAM, 0, -@Pars.num_pars@);
+                  @i @Pars.num_pars@ = @Pars.1.num_pars@ + 1;
+                @}
+
+               | ID
+               @{
+                   @i @Pars.pars@ = table_add_symbol(new_table(), @ID.name@, SYMBOL_TYPE_PARAM, 0, -1);
+                   @i @Pars.num_pars@ = 1;
+                @}
+
+               ; 
+Stats:           Stat ';' Stats
+               @{
+                  @i @Stat.in_symbols@ = @Stats.symbols@;
+                  @i @Stats.1.symbols@ = @Stat.out_symbols@;
+                  @i @Stats.defined_vars@ = @Stat.defined_vars@ + @Stats.1.defined_vars@;
+                  @i @Stats.1.stack_offset@ = @Stats.stack_offset@ + @Stat.defined_vars@ * 8;
+
+                  @codegen /* write_tree(@Stat.node@, 0); */ burm_label(@Stat.node@); burm_reduce(@Stat.node@, 1);
+               @}
+
+               |
+               @{ @i @Stats.defined_vars@ = 0; @}
+
+               ;  
+Stat:            VAR ID ASSIGN Expr
+               @{
+                  @i @Stat.out_symbols@ = table_add_symbol(clone_table(@Stat.in_symbols@), @ID.name@, SYMBOL_TYPE_VAR, 0, 0);
+                  @i @Expr.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = (treenode *)NULL;
+                  @i @Stat.defined_vars@ = 1;
+               @}
+
+               | Lexpr ASSIGN Expr
+               @{
+                  @i @Stat.out_symbols@ = @Stat.in_symbols@;
+                  @i @Lexpr.symbols@ = @Stat.in_symbols@;
+                  @i @Expr.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = (treenode *)NULL;
+                  @i @Stat.defined_vars@ = 0;
+               @}
+
+               | IF Bool THEN Stats END
+               @{
+                  @i @Bool.symbols@ = @Stat.in_symbols@;
+                  @i @Stats.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.out_symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = (treenode *)NULL;
+               @}
+
+               | 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@;
+                  @i @Stat.node@ = (treenode *)NULL;
+                  @i @Stat.defined_vars@ = @Stats.defined_vars@ + @Stats.1.defined_vars@;
+               @}
+
+               | WHILE Bool DO Stats END
+               @{
+                  @i @Bool.symbols@ = @Stat.in_symbols@;
+                  @i @Stats.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.out_symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = (treenode *)NULL;
+               @}
+
+               | Call
+               @{
+                  @i @Call.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.out_symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = (treenode *)NULL;
+                  @i @Stat.defined_vars@ = 0;
+               @}
+
+               | RETURN Expr
+               @{
+                  @i @Expr.symbols@ = @Stat.in_symbols@;
+                  @i @Stat.out_symbols@ = @Stat.in_symbols@;
+                  @i @Stat.node@ = new_node(OP_Return, @Expr.node@, (treenode *)NULL);
+
+                  @reg @Stat.node@->reg = get_next_reg((char *)NULL, 0); @Expr.node@->reg = @Stat.node@->reg;
+                  @i @Stat.defined_vars@ = 0;
+               @}
+
+               ;
+Lexpr:           ID
+               @{
+                  @i @Lexpr.node@ = (treenode *)NULL;
+                  @check check_variable(@Lexpr.symbols@, @ID.name@);
+               @}
+
+               | Field
+               ;
+Expr:            '-' Term
+               @{
+                  @i @Expr.node@ = new_node(OP_Negation, @Term.node@, (treenode *)NULL);
+
+                  @reg @Term.node@->reg = @Expr.node@->reg;
+               @}
+
+               | Term
+               @{ @reg @Term.node@->reg = @Expr.node@->reg; @}
+
+               | Term Plusterm
+               @{
+                  @i @Expr.node@ = new_node(OP_Addition, @Term.node@, @Plusterm.node@);
+                  @i @Expr.immediate@ = @Term.immediate@ && @Plusterm.immediate@;
+
+                  @reg if(!@Plusterm.immediate@) { @Plusterm.node@->reg = @Expr.node@->reg; @Term.node@->reg = (@Term.node@->op==OP_ID && table_lookup(@Term.symbols@, @Term.node@->name)->type==SYMBOL_TYPE_PARAM) ? get_param_reg(-table_lookup(@Term.symbols@, @Term.node@->name)->stack_offset) : get_next_reg(@Plusterm.node@->reg, @Expr.node@->skip_reg); @Plusterm.node@->skip_reg = 1; } else { @Term.node@->reg = @Expr.node@->reg; @Plusterm.node@->reg = get_next_reg(@Term.node@->reg, @Expr.node@->skip_reg); }
+               @}
+
+               | Term Malterm
+               @{
+                  @i @Expr.node@ = new_node(OP_Multiplication, @Term.node@, @Malterm.node@);
+                  @i @Expr.immediate@ = @Term.immediate@ && @Malterm.immediate@;
+
+                  @reg if(!@Malterm.immediate@) { @Malterm.node@->reg = @Expr.node@->reg; @Term.node@->reg = (@Term.node@->op==OP_ID && table_lookup(@Term.symbols@, @Term.node@->name)->type==SYMBOL_TYPE_PARAM) ? get_param_reg(-table_lookup(@Term.symbols@, @Term.node@->name)->stack_offset) : get_next_reg(@Malterm.node@->reg, @Expr.node@->skip_reg); @Malterm.node@->skip_reg = 1; } else { @Term.node@-> reg = @Expr.node@->reg; @Malterm.node@->reg = get_next_reg(@Term.node@->reg, @Expr.node@->skip_reg); }
+               @}
+
+               ;
+
+Plusterm:        '+' Term Plusterm
+               @{
+                  @i @Plusterm.node@ = new_node(OP_Addition, @Term.node@, @Plusterm.1.node@);
+                  @i @Plusterm.immediate@ = @Term.immediate@ && @Plusterm.1.immediate@;
+
+                  @reg @Plusterm.1.node@->reg = @Plusterm.node@->reg; @Term.node@->reg = (@Term.node@->op==OP_ID && table_lookup(@Term.symbols@, @Term.node@->name)->type==SYMBOL_TYPE_PARAM) ? get_param_reg(-table_lookup(@Term.symbols@, @Term.node@->name)->stack_offset) : get_next_reg(@Plusterm.1.node@->reg, @Plusterm.node@->skip_reg); 
+               @}
+
+               | '+' Term
+               @{ @reg @Term.node@->reg = @Plusterm.node@->reg; @}
+
+               ;
+
+Malterm:         '*' Term Malterm
+               @{
+                  @i @Malterm.node@ = new_node(OP_Multiplication, @Term.node@, @Malterm.1.node@);
+                  @i @Malterm.immediate@ = @Term.immediate@ && @Malterm.1.immediate@;
+
+                  @reg @Malterm.1.node@->reg = @Malterm.node@->reg; @Term.node@->reg = (@Term.node@->op==OP_ID && table_lookup(@Term.symbols@, @Term.node@->name)->type==SYMBOL_TYPE_PARAM) ? get_param_reg(-table_lookup(@Term.symbols@, @Term.node@->name)->stack_offset) : get_next_reg(@Malterm.1.node@->reg, @Malterm.node@->skip_reg); 
+               @}
+
+                       | '*' Term
+               @{ @reg @Term.node@->reg = @Malterm.node@->reg; @}
+
+               ;
+Term:            '(' Expr ')'
+               @{ @reg @Expr.node@->reg = @Term.node@->reg; @}
+
+               | ID
+               @{
+                  @i @Term.node@ = new_named_leaf_value(OP_ID, @ID.name@, (table_lookup(@Term.symbols@, @ID.name@)==NULL) ? 0 : table_lookup(@Term.symbols@, @ID.name@)->stack_offset);
+                  @i @Term.immediate@ = 0;
+
+                  @check check_variable(@Term.symbols@, @ID.name@);
+               @}
+
+               | NUM
+               @{
+                  @i @Term.node@ = new_number_leaf(@NUM.value@);
+                  @i @Term.immediate@ = 1;
+               @}
+
+               | Call
+               @{ @i @Term.immediate@ = 0; @}
+
+               | Field
+               @{
+                  @i @Term.immediate@ = 0;
+
+                  @reg @Field.node@->reg = @Term.node@->reg;
+               @}
+
+               ;
+
+Bool:            Bterm
+               | Bterm Orterm
+               @{ @i @Bool.node@ = new_node(OP_Disjunction, @Bterm.node@, @Orterm.node@); @}
+
+               | NOT Bterm
+               @{ @i @Bool.node@ = new_node(OP_Not, @Bterm.node@, (treenode *)NULL); @}
+
+               ;
+
+Orterm:                  OR Bterm Orterm
+               @{ @i @Orterm.node@ = new_node(OP_Disjunction, @Bterm.node@, @Orterm.1.node@); @}
+
+               | OR Bterm
+               ;
+
+Bterm:           Term GREATER Term
+               @{ @i @Bterm.node@ = new_node(OP_Greater, @Term.node@, @Term.1.node@); @}
+
+               | Term '=' Term
+               @{ @i @Bterm.node@ = new_node(OP_Equal, @Term.node@, @Term.1.node@); @}
+
+               | '(' Bool ')'
+               ;
+
+Field:           Term '.' ID
+               @{
+                  @i @Field.node@ = new_node_value(OP_Field, @Term.node@, new_named_leaf(OP_ID, @ID.name@), table_lookup(@Field.symbols@, @ID.name@)==(struct symbol_t *)NULL ? 0 : table_lookup(@Field.symbols@, @ID.name@)->stack_offset);
+
+                  @check check_field(@Field.symbols@, @ID.name@);
+
+                  @reg @Term.node@->reg = @Field.node@->reg; @Field.node@->kids[1]->reg = get_next_reg(@Field.node@->reg, 0); 
+               @}
+
+               ;
+
+Call:            ID '(' Exprs ')'
+               @{ @i @Call.node@ = new_node(OP_Call, new_named_leaf(OP_ID, @ID.name@), @Exprs.node@); @}
+
+               | ID '(' ')'
+               @{ @i @Call.node@ = new_node(OP_Call, new_named_leaf(OP_ID, @ID.name@), NULL); @}
+
+               ;
+
+Exprs:           Expr
+               | Exprs ',' Expr
+               @{ @i @Exprs.node@ = new_node(OP_Exprs, @Exprs.1.node@, @Expr.node@); @}
+
+               ;
+
+%%
+
+extern int yylex();
+extern int yylineno;
+
+int yyerror(char *error_text) {
+       fprintf(stderr,"Line %i: %s\n",yylineno, error_text);
+       exit(2);
+}
+
+int main(int argc, char **argv) {
+       yyparse();
+       return 0;
+}
+