package de.skuzzle.polly.core.parser.ast.visitor; import java.io.PrintStream; import de.skuzzle.polly.core.parser.ast.Identifier; import de.skuzzle.polly.core.parser.ast.Node; import de.skuzzle.polly.core.parser.ast.ResolvableIdentifier; import de.skuzzle.polly.core.parser.ast.Root; import de.skuzzle.polly.core.parser.ast.declarations.Declaration; import de.skuzzle.polly.core.parser.ast.declarations.types.Type; import de.skuzzle.polly.core.parser.ast.expressions.Assignment; import de.skuzzle.polly.core.parser.ast.expressions.Call; import de.skuzzle.polly.core.parser.ast.expressions.Delete; import de.skuzzle.polly.core.parser.ast.expressions.Expression; import de.skuzzle.polly.core.parser.ast.expressions.NamespaceAccess; import de.skuzzle.polly.core.parser.ast.expressions.Native; import de.skuzzle.polly.core.parser.ast.expressions.OperatorCall; import de.skuzzle.polly.core.parser.ast.expressions.VarAccess; import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ListLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal; import de.skuzzle.polly.core.parser.ast.expressions.literals.ProductLiteral; import de.skuzzle.polly.core.parser.util.PreOrderDotBuilder; public class ASTVisualizer extends DepthFirstVisitor { private PreOrderDotBuilder dotBuilder; public void visualize(Node root, PrintStream out) throws ASTTraversalException { this.dotBuilder = new PreOrderDotBuilder(out, false); root.visit(this); this.dotBuilder.finish(); } private void printExpression(String label, Expression exp) { final StringBuilder typesBuilder = new StringBuilder(); for (final Type t : exp.getTypes()) { typesBuilder.append(t); typesBuilder.append("\\n"); } this.dotBuilder.printNode(exp, label, "Unique: " + exp.getUnique(), "Types:\\n" + typesBuilder.toString(), exp.getPosition().toString()); } @Override public int before(OperatorCall node) throws ASTTraversalException { this.printExpression("OperatorCall: " + node.getOperator().getId(), node); return CONTINUE; } @Override public int before(Call node) throws ASTTraversalException { this.printExpression("Call", node); return CONTINUE; } @Override public int before(Literal node) throws ASTTraversalException { this.printExpression(node.toString(), node); return CONTINUE; } @Override public int before(ProductLiteral node) throws ASTTraversalException { this.printExpression("Product", node); return CONTINUE; } @Override public int before(NamespaceAccess node) throws ASTTraversalException { this.printExpression("Access", node); return CONTINUE; } @Override public int before(Assignment node) throws ASTTraversalException { this.printExpression("Assignment", node); return CONTINUE; } @Override public int before(FunctionLiteral node) throws ASTTraversalException { this.printExpression("Function", node); return CONTINUE; } @Override public int before(Native node) throws ASTTraversalException { this.printExpression("Native", node); return CONTINUE; } @Override public int before(Identifier node) throws ASTTraversalException { this.dotBuilder.printNode(node, node.getId(), node.getPosition().toString()); return CONTINUE; } @Override public int before(ListLiteral node) throws ASTTraversalException { this.printExpression("List", node); return CONTINUE; } @Override public int before(ResolvableIdentifier node) throws ASTTraversalException { this.dotBuilder.printNode(node.getId(), node.getPosition().toString()); return CONTINUE; } @Override public int before(Delete node) throws ASTTraversalException { this.printExpression("Delete", node); return CONTINUE; } @Override public int before(Declaration node) throws ASTTraversalException { this.dotBuilder.printNode(node, "Declaration: " + node.getName().getId(), "Unique: " + node.getType()); return CONTINUE; } @Override public int before(Root node) throws ASTTraversalException { this.dotBuilder.printNode(node, "Root", node.getPosition().toString()); return CONTINUE; } @Override public boolean visit(VarAccess node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } this.printExpression("VarAccess: " + node.getIdentifier().getId(), node); return this.before(node) == CONTINUE; } @Override public int after(NamespaceAccess node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Assignment node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Call node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(FunctionLiteral node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(ProductLiteral node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Native node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Identifier node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(ListLiteral node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Literal node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(OperatorCall node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(ResolvableIdentifier node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Root node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(VarAccess node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Declaration node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } @Override public int after(Delete node) throws ASTTraversalException { this.dotBuilder.pop(node); return CONTINUE; } }