}
markedStates.add(s); // mark this node as completed.
// first add this node
ST stateST;
if ( s.isAcceptState() ) {
stateST = stlib.getInstanceOf("stopstate");
}
else {
stateST = stlib.getInstanceOf("state");
}
stateST.add("name", getStateLabel(s));
dot.add("states", stateST);
if ( s.isAcceptState() ) {
return; // don't go past end of rule node to the follow states
}
// special case: if decision point, then line up the alt start states
// unless it's an end of block
if ( ((NFAState)s).isDecisionState() ) {
GrammarAST n = ((NFAState)s).associatedASTNode;
if ( n!=null && n.getType()!=ANTLRParser.EOB ) {
ST rankST = stlib.getInstanceOf("decision-rank");
NFAState alt = (NFAState)s;
while ( alt!=null ) {
rankST.add("states", getStateLabel(alt));
if ( alt.transition[1] !=null ) {
alt = (NFAState)alt.transition[1].target;
}
else {
alt=null;
}
}
dot.add("decisionRanks", rankST);
}
}
// make a DOT edge for each transition
ST edgeST;
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition edge = s.transition(i);
if ( edge instanceof RuleClosureTransition ) {
RuleClosureTransition rr = ((RuleClosureTransition)edge);
// don't jump to other rules, but display edge to follow node
edgeST = stlib.getInstanceOf("edge");
if ( rr.rule.grammar != grammar ) {
edgeST.add("label", "<" + rr.rule.grammar.name + "." + rr.rule.name + ">");
}
else {
edgeST.add("label", "<" + rr.rule.name + ">");
}
edgeST.add("src", getStateLabel(s));
edgeST.add("target", getStateLabel(rr.followState));
edgeST.add("arrowhead", arrowhead);
dot.add("edges", edgeST);
walkRuleNFACreatingDOT(dot, rr.followState);
continue;
}
if ( edge.isAction() ) {
edgeST = stlib.getInstanceOf("action-edge");
}
else if ( edge.isEpsilon() ) {
edgeST = stlib.getInstanceOf("epsilon-edge");
}
else {
edgeST = stlib.getInstanceOf("edge");
}
edgeST.add("label", getEdgeLabel(edge));
edgeST.add("src", getStateLabel(s));
edgeST.add("target", getStateLabel(edge.target));
edgeST.add("arrowhead", arrowhead);
dot.add("edges", edgeST);
walkRuleNFACreatingDOT(dot, edge.target); // keep walkin'
}
}