package de.skuzzle.polly.core.parser.util;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import de.skuzzle.polly.core.parser.ast.Node;
import de.skuzzle.polly.tools.iterators.ArrayIterator;
import de.skuzzle.polly.tools.strings.StringUtils;
public class DotBuilder {
protected final PrintStream out;
protected int nodeIdx;
protected final Map<Node, Integer> nodes;
public DotBuilder(PrintStream out) {
this.out = out;
this.nodes = new HashMap<Node, Integer>();
this.out.println("graph \"name\"");
this.out.println("{");
this.out.println("node [shape=Mrecord];");
this.out.println("graph[bgcolor=white, ordering=out, concentrate=true];");
}
public void finish() {
this.out.println("}");
}
public void printNode(Node node, String...attributes) {
Integer i = this.nodes.get(node);
if (i != null) {
return;
}
i = this.nodeIdx++;
this.nodes.put(node, i);
this.out.print("n");
this.out.print(i);
this.out.print("[shape=Mrecord, fontname=\"Consolas\", label=\"{");
final Iterator<String> it = ArrayIterator.get(attributes);
while(it.hasNext()) {
this.out.print(this.simpleEscape(it.next()));
if (it.hasNext()) {
this.out.print("|");
}
}
this.out.println("}\"];");
}
public void printEdge(Node start, Node target, String label) {
this.printEdge(start, target, label, "solid", true);
}
public void printEdge(Node start, Node target, String label, String style,
boolean constraint) {
final Integer startIdx = this.nodes.get(start);
final Integer targetIdx = this.nodes.get(target);
if (startIdx == null) {
throw new IllegalStateException("no start for node " + start);
} else if (targetIdx == null) {
throw new IllegalStateException("no target for node " + target);
}
this.out.print("n");
this.out.print(startIdx);
this.out.print("--");
this.out.print("n");
this.out.print(targetIdx);
this.out.print(" [fontname=\"Consolas\", headport=n,tailport=s,constraint=");
this.out.print(constraint);
this.out.print(",label=\"");
this.out.print(label);
this.out.print("\", style=\"");
this.out.print(style);
this.out.println("\"];");
}
private final static char[] ESCAPES = {'?', '<', '>'};
private final static String[] REPLACEMENTS = {"\\?", "<", ">"};
private String simpleEscape(String s) {
return StringUtils.replace(s, ESCAPES, REPLACEMENTS);
}
}