00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package org.antlr.runtime.tree;
00029
00030 import org.antlr.stringtemplate.StringTemplate;
00031
00032 import java.util.HashMap;
00033
00053 public class DOTTreeGenerator {
00054
00055 public static StringTemplate _treeST =
00056 new StringTemplate(
00057 "digraph {\n" +
00058 " ordering=out;\n" +
00059 " ranksep=.4;\n" +
00060 " node [shape=plaintext, fixedsize=true, fontsize=11, fontname=\"Courier\",\n" +
00061 " width=.25, height=.25];\n" +
00062 " edge [arrowsize=.5]\n" +
00063 " $nodes$\n" +
00064 " $edges$\n" +
00065 "}\n");
00066
00067 public static StringTemplate _nodeST =
00068 new StringTemplate("$name$ [label=\"$text$\"];\n");
00069
00070 public static StringTemplate _edgeST =
00071 new StringTemplate("$parent$ -> $child$ // \"$parentText$\" -> \"$childText$\"\n");
00072
00074 HashMap nodeToNumberMap = new HashMap();
00075
00077 int nodeNumber = 0;
00078
00079 public StringTemplate toDOT(Object tree,
00080 TreeAdaptor adaptor,
00081 StringTemplate _treeST,
00082 StringTemplate _edgeST)
00083 {
00084 StringTemplate treeST = _treeST.getInstanceOf();
00085 nodeNumber = 0;
00086 toDOTDefineNodes(tree, adaptor, treeST);
00087 nodeNumber = 0;
00088 toDOTDefineEdges(tree, adaptor, treeST);
00089
00090
00091
00092
00093
00094
00095 return treeST;
00096 }
00097
00098 public StringTemplate toDOT(Object tree,
00099 TreeAdaptor adaptor)
00100 {
00101 return toDOT(tree, adaptor, _treeST, _edgeST);
00102 }
00103
00121 public StringTemplate toDOT(Tree tree) {
00122 return toDOT(tree, new CommonTreeAdaptor());
00123 }
00124
00125 protected void toDOTDefineNodes(Object tree,
00126 TreeAdaptor adaptor,
00127 StringTemplate treeST)
00128 {
00129 if ( tree==null ) {
00130 return;
00131 }
00132 int n = adaptor.getChildCount(tree);
00133 if ( n==0 ) {
00134
00135
00136 return;
00137 }
00138
00139
00140 StringTemplate parentNodeST = getNodeST(adaptor, tree);
00141 treeST.setAttribute("nodes", parentNodeST);
00142
00143
00144 for (int i = 0; i < n; i++) {
00145 Object child = adaptor.getChild(tree, i);
00146 StringTemplate nodeST = getNodeST(adaptor, child);
00147 treeST.setAttribute("nodes", nodeST);
00148 toDOTDefineNodes(child, adaptor, treeST);
00149 }
00150 }
00151
00152 protected void toDOTDefineEdges(Object tree,
00153 TreeAdaptor adaptor,
00154 StringTemplate treeST)
00155 {
00156 if ( tree==null ) {
00157 return;
00158 }
00159 int n = adaptor.getChildCount(tree);
00160 if ( n==0 ) {
00161
00162
00163 return;
00164 }
00165
00166 String parentName = "n"+getNodeNumber(tree);
00167
00168
00169 String parentText = adaptor.getText(tree);
00170 for (int i = 0; i < n; i++) {
00171 Object child = adaptor.getChild(tree, i);
00172 String childText = adaptor.getText(child);
00173 String childName = "n"+getNodeNumber(child);
00174 StringTemplate edgeST = _edgeST.getInstanceOf();
00175 edgeST.setAttribute("parent", parentName);
00176 edgeST.setAttribute("child", childName);
00177 edgeST.setAttribute("parentText", parentText);
00178 edgeST.setAttribute("childText", childText);
00179 treeST.setAttribute("edges", edgeST);
00180 toDOTDefineEdges(child, adaptor, treeST);
00181 }
00182 }
00183
00184 protected StringTemplate getNodeST(TreeAdaptor adaptor, Object t) {
00185 String text = adaptor.getText(t);
00186 StringTemplate nodeST = _nodeST.getInstanceOf();
00187 String uniqueName = "n"+getNodeNumber(t);
00188 nodeST.setAttribute("name", uniqueName);
00189 if (text!=null) text = text.replaceAll("\"", "\\\\\"");
00190 nodeST.setAttribute("text", text);
00191 return nodeST;
00192 }
00193
00194 protected int getNodeNumber(Object t) {
00195 Integer nI = (Integer)nodeToNumberMap.get(t);
00196 if ( nI!=null ) {
00197 return nI.intValue();
00198 }
00199 else {
00200 nodeToNumberMap.put(t, new Integer(nodeNumber));
00201 nodeNumber++;
00202 return nodeNumber-1;
00203 }
00204 }
00205 }