From 217c565e0f74e4d75f7538b8a333b31f5ade94b1 Mon Sep 17 00:00:00 2001 From: "M.Scholz" Date: Fri, 23 Dec 2011 14:10:37 +0100 Subject: [PATCH] =?UTF-8?q?compiler=20L=C3=B6sung=20=C3=9Cbung=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2. Uebung/solution/ConstantFolding.java | 523 ++++++++++++++++++ .../2. Uebung/solution/SymbolTable.java | 72 +++ .../Uebungen/2. Uebung/solution/solution.odt | Bin 0 -> 9639 bytes 3 files changed, 595 insertions(+) create mode 100644 ws2011/Compiler I/Uebungen/2. Uebung/solution/ConstantFolding.java create mode 100644 ws2011/Compiler I/Uebungen/2. Uebung/solution/SymbolTable.java create mode 100644 ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt 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 0000000000000000000000000000000000000000..93e5f3dfdcb1dc4695316c867bf644f0f16c736d GIT binary patch literal 9639 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 literal 0 HcmV?d00001