Antlr4.Tool.DOTGenerator.GetDOT C# (CSharp) Method

GetDOT() public method

public GetDOT ( ATNState startState, string ruleNames, bool isLexer ) : string
startState Antlr4.Runtime.Atn.ATNState
ruleNames string
isLexer bool
return string
        public virtual string GetDOT(ATNState startState, string[] ruleNames, bool isLexer)
        {
            if (startState == null)
                return null;

            // The output DOT graph for visualization
            ISet<ATNState> markedStates = new HashSet<ATNState>();
            Template dot = stlib.GetInstanceOf("atn");
            dot.Add("startState", startState.stateNumber);
            dot.Add("rankdir", rankdir);

            Queue<ATNState> work = new Queue<ATNState>();

            work.Enqueue(startState);
            while (work.Count > 0)
            {
                ATNState s = work.Peek();
                if (markedStates.Contains(s))
                {
                    work.Dequeue();
                    continue;
                }
                markedStates.Add(s);

                // don't go past end of rule node to the follow states
                if (s is RuleStopState)
                    continue;

                // special case: if decision point, then line up the alt start states
                // unless it's an end of block
                //			if ( s instanceof BlockStartState ) {
                //				ST rankST = stlib.getInstanceOf("decision-rank");
                //				DecisionState alt = (DecisionState)s;
                //				for (int i=0; i<alt.getNumberOfTransitions(); i++) {
                //					ATNState target = alt.transition(i).target;
                //					if ( target!=null ) {
                //						rankST.add("states", target.stateNumber);
                //					}
                //				}
                //				dot.add("decisionRanks", rankST);
                //			}

                // make a DOT edge for each transition
                Template edgeST;
                for (int i = 0; i < s.NumberOfTransitions; i++)
                {
                    Transition edge = s.Transition(i);
                    if (edge is RuleTransition)
                    {
                        RuleTransition rr = ((RuleTransition)edge);
                        // don't jump to other rules, but display edge to follow node
                        edgeST = stlib.GetInstanceOf("edge");

                        string label = "<" + ruleNames[rr.ruleIndex];
                        if (((RuleStartState)rr.target).isPrecedenceRule)
                        {
                            label += "[" + rr.precedence + "]";
                        }
                        label += ">";

                        edgeST.Add("label", label);
                        edgeST.Add("src", "s" + s.stateNumber);
                        edgeST.Add("target", "s" + rr.followState.stateNumber);
                        edgeST.Add("arrowhead", arrowhead);
                        dot.Add("edges", edgeST);
                        work.Enqueue(rr.followState);
                        continue;
                    }
                    if (edge is ActionTransition)
                    {
                        edgeST = stlib.GetInstanceOf("action-edge");
                        edgeST.Add("label", GetEdgeLabel(edge.ToString()));
                    }
                    else if (edge is AbstractPredicateTransition)
                    {
                        edgeST = stlib.GetInstanceOf("edge");
                        edgeST.Add("label", GetEdgeLabel(edge.ToString()));
                    }
                    else if (edge.IsEpsilon)
                    {
                        edgeST = stlib.GetInstanceOf("epsilon-edge");
                        edgeST.Add("label", GetEdgeLabel(edge.ToString()));
                        bool loopback = false;
                        if (edge.target is PlusBlockStartState)
                        {
                            loopback = s.Equals(((PlusBlockStartState)edge.target).loopBackState);
                        }
                        else if (edge.target is StarLoopEntryState)
                        {
                            loopback = s.Equals(((StarLoopEntryState)edge.target).loopBackState);
                        }
                        edgeST.Add("loopback", loopback);
                    }
                    else if (edge is AtomTransition)
                    {
                        edgeST = stlib.GetInstanceOf("edge");
                        AtomTransition atom = (AtomTransition)edge;
                        string label = atom.label.ToString();
                        if (isLexer)
                            label = "'" + GetEdgeLabel(((char)atom.label).ToString()) + "'";
                        else if (grammar != null)
                            label = grammar.GetTokenDisplayName(atom.label);
                        edgeST.Add("label", GetEdgeLabel(label));
                    }
                    else if (edge is SetTransition)
                    {
                        edgeST = stlib.GetInstanceOf("edge");
                        SetTransition set = (SetTransition)edge;
                        string label = set.Label.ToString();
                        if (isLexer)
                            label = set.Label.ToString(true);
                        else if (grammar != null)
                            label = set.Label.ToString(grammar.GetVocabulary());
                        if (edge is NotSetTransition)
                            label = "~" + label;
                        edgeST.Add("label", GetEdgeLabel(label));
                    }
                    else if (edge is RangeTransition)
                    {
                        edgeST = stlib.GetInstanceOf("edge");
                        RangeTransition range = (RangeTransition)edge;
                        string label = range.Label.ToString();
                        if (isLexer)
                            label = range.ToString();
                        else if (grammar != null)
                            label = range.Label.ToString(grammar.GetVocabulary());
                        edgeST.Add("label", GetEdgeLabel(label));
                    }
                    else
                    {
                        edgeST = stlib.GetInstanceOf("edge");
                        edgeST.Add("label", GetEdgeLabel(edge.ToString()));
                    }
                    edgeST.Add("src", "s" + s.stateNumber);
                    edgeST.Add("target", "s" + edge.target.stateNumber);
                    edgeST.Add("arrowhead", arrowhead);
                    if (s.NumberOfTransitions > 1)
                    {
                        edgeST.Add("transitionIndex", i);
                    }
                    else
                    {
                        edgeST.Add("transitionIndex", false);
                    }
                    dot.Add("edges", edgeST);
                    work.Enqueue(edge.target);
                }
            }

            // define nodes we visited (they will appear first in DOT output)
            // this is an example of ST's lazy eval :)
            // define stop state first; seems to be a bug in DOT where doublecircle
            // shape only works if we define them first. weird.
            //		ATNState stopState = startState.atn.ruleToStopState.get(startState.rule);
            //		if ( stopState!=null ) {
            //			ST st = stlib.getInstanceOf("stopstate");
            //			st.add("name", "s"+stopState.stateNumber);
            //			st.add("label", getStateLabel(stopState));
            //			dot.add("states", st);
            //		}
            foreach (ATNState s in markedStates)
            {
                if (!(s is RuleStopState))
                    continue;
                Template st = stlib.GetInstanceOf("stopstate");
                st.Add("name", "s" + s.stateNumber);
                st.Add("label", GetStateLabel(s));
                dot.Add("states", st);
            }

            foreach (ATNState s in markedStates)
            {
                if (s is RuleStopState)
                    continue;
                Template st = stlib.GetInstanceOf("state");
                st.Add("name", "s" + s.stateNumber);
                st.Add("label", GetStateLabel(s));
                st.Add("transitions", s.Transitions);
                dot.Add("states", st);
            }

            return dot.Render();
        }

Same methods

DOTGenerator::GetDOT ( ATNState startState ) : string
DOTGenerator::GetDOT ( ATNState startState, bool isLexer ) : string
DOTGenerator::GetDOT ( DFA dfa, bool isLexer ) : string

Usage Example

Example #1
0
        public virtual void GenerateATNs(Grammar g)
        {
            DOTGenerator dotGenerator = new DOTGenerator(g);
            IList<Grammar> grammars = new List<Grammar>();
            grammars.Add(g);
            IList<Grammar> imported = g.GetAllImportedGrammars();
            if (imported != null)
            {
                foreach (Grammar importedGrammar in imported)
                    grammars.Add(importedGrammar);
            }

            foreach (Grammar ig in grammars)
            {
                foreach (Rule r in ig.rules.Values)
                {
                    try
                    {
                        string dot = dotGenerator.GetDOT(g.atn.ruleToStartState[r.index], g.IsLexer());
                        if (dot != null)
                        {
                            WriteDOTFile(g, r, dot);
                        }
                    }
                    catch (IOException ioe)
                    {
                        errMgr.ToolError(ErrorType.CANNOT_WRITE_FILE, ioe);
                    }
                }
            }
        }