compiler Lösung Übung 2
This commit is contained in:
parent
ef42d862b7
commit
217c565e0f
@ -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 <code>true</code> if the given expression represents constant value.
|
||||
* This value can be a boolean or integer.
|
||||
* @param e the expression to test
|
||||
* @return <code>true</code> 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
|
||||
}
|
||||
|
||||
}
|
||||
@ -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<String, Stack<Declaration>> symtab;
|
||||
private List<List<String>> scopeStack;
|
||||
|
||||
public SymbolTable () {
|
||||
symtab = new HashMap<String, Stack<Declaration>>();
|
||||
scopeStack = new ArrayList<List<String>>();
|
||||
}
|
||||
|
||||
// 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<String>());
|
||||
}
|
||||
|
||||
// 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<Declaration>());
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt
Normal file
BIN
ws2011/Compiler I/Uebungen/2. Uebung/solution/solution.odt
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user