public virtual string GetDOT(DFA dfa, bool isLexer)
{
if (dfa.s0.Get() == null)
return null;
Template dot = stlib.GetInstanceOf("dfa");
dot.Add("name", "DFA" + dfa.decision);
dot.Add("startState", dfa.s0.Get().stateNumber);
// dot.add("useBox", Tool.internalOption_ShowATNConfigsInDFA);
dot.Add("rankdir", rankdir);
// define stop states first; seems to be a bug in DOT where doublecircle
foreach (DFAState d in dfa.states.Keys)
{
if (!d.IsAcceptState)
continue;
Template st = stlib.GetInstanceOf("stopstate");
st.Add("name", "s" + d.stateNumber);
st.Add("label", GetStateLabel(d));
dot.Add("states", st);
}
foreach (DFAState d in dfa.states.Keys)
{
if (d.IsAcceptState)
continue;
if (d.stateNumber == int.MaxValue)
continue;
Template st = stlib.GetInstanceOf("state");
st.Add("name", "s" + d.stateNumber);
st.Add("label", GetStateLabel(d));
dot.Add("states", st);
}
foreach (DFAState d in dfa.states.Keys)
{
IDictionary<int, DFAState> edges = d.EdgeMap;
foreach (KeyValuePair<int, DFAState> entry in edges)
{
DFAState target = entry.Value;
if (target == null)
continue;
if (target.stateNumber == int.MaxValue)
continue;
int ttype = entry.Key;
string label = ttype.ToString();
if (isLexer)
label = "'" + GetEdgeLabel(((char)ttype).ToString()) + "'";
else if (grammar != null)
label = grammar.GetTokenDisplayName(ttype);
Template st = stlib.GetInstanceOf("edge");
st.Add("label", label);
st.Add("src", "s" + d.stateNumber);
st.Add("target", "s" + target.stateNumber);
st.Add("arrowhead", arrowhead);
dot.Add("edges", st);
}
}
string output = dot.Render();
return Utils.SortLinesInString(output);
}