diff --git a/ws2011/Compiler I/Uebungen/2. Uebung/solution/ConstantFolding.java b/ws2011/Compiler I/Uebungen/2. Uebung/solution/ConstantFolding.java new file mode 100644 index 00000000..dd0047b4 --- /dev/null +++ b/ws2011/Compiler I/Uebungen/2. Uebung/solution/ConstantFolding.java @@ -0,0 +1,523 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package solution; +import Triangle.AbstractSyntaxTrees.AnyTypeDenoter; +import Triangle.AbstractSyntaxTrees.ArrayExpression; +import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter; +import Triangle.AbstractSyntaxTrees.AssignCommand; +import Triangle.AbstractSyntaxTrees.BinaryExpression; +import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.BoolTypeDenoter; +import Triangle.AbstractSyntaxTrees.CallCommand; +import Triangle.AbstractSyntaxTrees.CallExpression; +import Triangle.AbstractSyntaxTrees.CharTypeDenoter; +import Triangle.AbstractSyntaxTrees.CharacterExpression; +import Triangle.AbstractSyntaxTrees.CharacterLiteral; +import Triangle.AbstractSyntaxTrees.ConstActualParameter; +import Triangle.AbstractSyntaxTrees.ConstDeclaration; +import Triangle.AbstractSyntaxTrees.ConstFormalParameter; +import Triangle.AbstractSyntaxTrees.DotVname; +import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence; +import Triangle.AbstractSyntaxTrees.EmptyCommand; +import Triangle.AbstractSyntaxTrees.EmptyExpression; +import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter; +import Triangle.AbstractSyntaxTrees.Expression; +import Triangle.AbstractSyntaxTrees.FuncActualParameter; +import Triangle.AbstractSyntaxTrees.FuncDeclaration; +import Triangle.AbstractSyntaxTrees.FuncFormalParameter; +import Triangle.AbstractSyntaxTrees.Identifier; +import Triangle.AbstractSyntaxTrees.IfCommand; +import Triangle.AbstractSyntaxTrees.IfExpression; +import Triangle.AbstractSyntaxTrees.IntTypeDenoter; +import Triangle.AbstractSyntaxTrees.IntegerExpression; +import Triangle.AbstractSyntaxTrees.IntegerLiteral; +import Triangle.AbstractSyntaxTrees.LetCommand; +import Triangle.AbstractSyntaxTrees.LetExpression; +import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate; +import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate; +import Triangle.AbstractSyntaxTrees.Operator; +import Triangle.AbstractSyntaxTrees.ProcActualParameter; +import Triangle.AbstractSyntaxTrees.ProcDeclaration; +import Triangle.AbstractSyntaxTrees.ProcFormalParameter; +import Triangle.AbstractSyntaxTrees.Program; +import Triangle.AbstractSyntaxTrees.RecordExpression; +import Triangle.AbstractSyntaxTrees.RecordTypeDenoter; +import Triangle.AbstractSyntaxTrees.SequentialCommand; +import Triangle.AbstractSyntaxTrees.SequentialDeclaration; +import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter; +import Triangle.AbstractSyntaxTrees.SimpleVname; +import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleArrayAggregate; +import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter; +import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence; +import Triangle.AbstractSyntaxTrees.SingleRecordAggregate; +import Triangle.AbstractSyntaxTrees.SubscriptVname; +import Triangle.AbstractSyntaxTrees.TypeDeclaration; +import Triangle.AbstractSyntaxTrees.UnaryExpression; +import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration; +import Triangle.AbstractSyntaxTrees.VarActualParameter; +import Triangle.AbstractSyntaxTrees.VarDeclaration; +import Triangle.AbstractSyntaxTrees.VarFormalParameter; +import Triangle.AbstractSyntaxTrees.Visitor; +import Triangle.AbstractSyntaxTrees.VnameExpression; +import Triangle.AbstractSyntaxTrees.WhileCommand; +import Triangle.StdEnvironment; +import Triangle.SyntacticAnalyzer.SourcePosition; + +/** + * + * @author Michael + */ +public class ConstantFolding implements Visitor{ + + + + /** + * Returns true if the given expression represents constant value. + * This value can be a boolean or integer. + * @param e the expression to test + * @return true if the given expression represents constant value + */ + private boolean isConstant(Expression e) { + if(e instanceof IntegerExpression) + return true; + if(e instanceof VnameExpression) { + VnameExpression vname = (VnameExpression)e; + if(vname.V instanceof SimpleVname) + if(((SimpleVname)vname.V).I.spelling.equals(StdEnvironment.trueDecl.I.spelling) + || ((SimpleVname)vname.V).I.spelling.equals(StdEnvironment.falseDecl.I.spelling)) + return true; + } + return false; + } + + /** + * Returns the boolean value of the given expression that represents a boolean value. + * @param e a boolean value + * @return the boolean value of the given expression that represents a boolean value + */ + private boolean parseBoolean(Expression e) { + if(e instanceof VnameExpression) { + VnameExpression vname = (VnameExpression)e; + if(vname.V instanceof SimpleVname) + if(((SimpleVname)vname.V).I.spelling.equals(StdEnvironment.trueDecl.I.spelling)) + return true; + if(((SimpleVname)vname.V).I.spelling.equals(StdEnvironment.falseDecl.I.spelling)) + return false; + } + throw new RuntimeException(); + } + + /** + * Returns an expression representing the given boolean value. + * @param val the boolean value that will be represented by the returned expression + * @return an expression representing the given boolean value + */ + private Expression createBoolean(boolean val) { + Identifier iAST = new Identifier(val ? "true" : "false", new SourcePosition()); + iAST.decl = val ? StdEnvironment.trueDecl : StdEnvironment.falseDecl; + SimpleVname vAST = new SimpleVname(iAST, new SourcePosition()); + vAST.type = StdEnvironment.booleanType; + VnameExpression boolExpression = new VnameExpression(vAST, new SourcePosition()); + return boolExpression; + } + + + private Expression createInteger(int i){ + return new IntegerExpression(new IntegerLiteral(String.valueOf(i),null), null); + } + + @Override + public Object visitBinaryExpression(BinaryExpression ast, Object o) { + + boolean e1 = false; + boolean e2 = false; + if(isConstant(ast.E1)){ + //optimize E + try{ + boolean b = parseBoolean(ast.E1); + ast.E1 = createBoolean(b); + + + } catch (RuntimeException e) + { + ast.E1 = (IntegerExpression)ast.E1; + + } + e1 = true; + } + + if(isConstant(ast.E2)){ + //optimize E + try{ + boolean b = parseBoolean(ast.E2); + ast.E2 = createBoolean(b); + + } catch (RuntimeException e) + { + ast.E2 = (IntegerExpression)ast.E2; + + } + e2 = true; + } + + if(e1 & e2) { + if(ast.O.spelling.equals("+")){ + return createInteger( ast.E1.GETVALUE() + ast.E2.GETVALUE()); + + }else if(ast.O.spelling.equals("<")){ + + return createBoolean(ast.E1.GETVALUE() < ast.E2.GETVALUE()); + }else if(ast.O.spelling.equals("-")){ + + //.... + + } + + //Instead define a Operator which can execute itself: + return ast.O(ast.E1,ast.E2); + + } + + return ast; + + } + + @Override + public Object visitUnaryExpression(UnaryExpression ast, Object o) { + + boolean e1 = false; + if(isConstant(ast.E)){ + //optimize E + try{ + boolean b = parseBoolean(ast.E); + ast.E = createBoolean(b); + if(ast.O.spelling.equals("\\")){ + return createBoolean(!b); + } + + } catch (RuntimeException e) + { + ast.E = (IntegerExpression)ast.E; + } + + } + + return ast; + } + + + + + + + @Override + public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitUnaryOperatorDeclaration(UnaryOperatorDeclaration ast, Object o) { + return null; // not of interest + } + + + + + @Override + public Object visitAssignCommand(AssignCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitCallCommand(CallCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitEmptyCommand(EmptyCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIfCommand(IfCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitLetCommand(LetCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSequentialCommand(SequentialCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitWhileCommand(WhileCommand ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitArrayExpression(ArrayExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitCallExpression(CallExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitCharacterExpression(CharacterExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitEmptyExpression(EmptyExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIfExpression(IfExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIntegerExpression(IntegerExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitLetExpression(LetExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitRecordExpression(RecordExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitVnameExpression(VnameExpression ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitConstDeclaration(ConstDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitProcDeclaration(ProcDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitTypeDeclaration(TypeDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitVarDeclaration(VarDeclaration ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitMultipleArrayAggregate(MultipleArrayAggregate ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSingleArrayAggregate(SingleArrayAggregate ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitMultipleRecordAggregate(MultipleRecordAggregate ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSingleRecordAggregate(SingleRecordAggregate ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitConstFormalParameter(ConstFormalParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitFuncFormalParameter(FuncFormalParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitProcFormalParameter(ProcFormalParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitVarFormalParameter(VarFormalParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitEmptyFormalParameterSequence(EmptyFormalParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitMultipleFormalParameterSequence(MultipleFormalParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSingleFormalParameterSequence(SingleFormalParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitConstActualParameter(ConstActualParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitFuncActualParameter(FuncActualParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitProcActualParameter(ProcActualParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitVarActualParameter(VarActualParameter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitEmptyActualParameterSequence(EmptyActualParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitMultipleActualParameterSequence(MultipleActualParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSingleActualParameterSequence(SingleActualParameterSequence ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitAnyTypeDenoter(AnyTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitArrayTypeDenoter(ArrayTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitBoolTypeDenoter(BoolTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitCharTypeDenoter(CharTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitErrorTypeDenoter(ErrorTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSimpleTypeDenoter(SimpleTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIntTypeDenoter(IntTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitRecordTypeDenoter(RecordTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitMultipleFieldTypeDenoter(MultipleFieldTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSingleFieldTypeDenoter(SingleFieldTypeDenoter ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitCharacterLiteral(CharacterLiteral ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIdentifier(Identifier ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitIntegerLiteral(IntegerLiteral ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitOperator(Operator ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitDotVname(DotVname ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSimpleVname(SimpleVname ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitSubscriptVname(SubscriptVname ast, Object o) { + return null; // not of interest + } + + @Override + public Object visitProgram(Program ast, Object o) { + return null; // not of interest + } + +} diff --git a/ws2011/Compiler I/Uebungen/2. Uebung/solution/SymbolTable.java b/ws2011/Compiler I/Uebungen/2. Uebung/solution/SymbolTable.java new file mode 100644 index 00000000..61f78816 --- /dev/null +++ b/ws2011/Compiler I/Uebungen/2. Uebung/solution/SymbolTable.java @@ -0,0 +1,72 @@ +package Triangle.ContextualAnalyzer; + +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import Triangle.AbstractSyntaxTrees.Declaration; +import java.util.ArrayList; +import java.util.HashMap; + +public final class SymbolTable { + + private Map> symtab; + private List> scopeStack; + + public SymbolTable () { + symtab = new HashMap>(); + scopeStack = new ArrayList>(); + } + + // Opens a new level in the identification table, 1 higher than the + // current topmost level. + public void openScope () { + // new empty list + scopeStack.add(new ArrayList()); + } + + // Closes the topmost level in the identification table, discarding + // all entries belonging to that level. + public void closeScope () { + //delete from symtab + for(int i = 0; i < scopeStack.get(scopeStack.size() -1).size(); i++){ + if(symtab.containsKey(scopeStack.get(scopeStack.size() -1).get(i))){ + symtab.get(scopeStack.get(scopeStack.size() -1).get(i)).pop(); + if(symtab.get(scopeStack.get(scopeStack.size() -1).get(i)).empty()){ + symtab.remove(scopeStack.get(scopeStack.size() -1).get(i)); + } + } + } + // delete top list + scopeStack.remove(scopeStack.size()-1); + } + + // Makes a new entry in the identification table for the given identifier + // and attribute. The new entry belongs to the current level. + // duplicated is set to to true if there is already an entry for the + // same identifier at the current level. + public void enter (String id, Declaration attr) { + scopeStack.get(scopeStack.size()-1).add(id); + if(symtab.containsKey(id)){ + symtab.get(id).push(attr); + }else{ + symtab.put(id, new Stack()); + symtab.get(id).push(attr); + } + } + + // Finds an entry for the given identifier in the identification table, + // if any. If there are several entries for that identifier, finds the + // entry at the highest level, in accordance with the scope rules. + // Returns null if no entry is found. + // otherwise returns the attribute field of the entry found. + public Declaration retrieve (String id) { + + if(symtab.containsKey(id)){ + return symtab.get(id).firstElement(); + } + + return null; + } + +} diff --git a/ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt b/ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt new file mode 100644 index 00000000..93e5f3df Binary files /dev/null and b/ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt differ