예제 #1
0
 public virtual string Serialize( State s )
 {
     if ( s == null )
     {
         return "<no automaton>";
     }
     return Serialize( s, true );
 }
예제 #2
0
 protected virtual string GetStateLabel( State s )
 {
     if ( s == null )
     {
         return "null";
     }
     string stateLabel = s.stateNumber.ToString();
     if ( s is DFAState )
     {
         StringBuffer buf = new StringBuffer( 250 );
         buf.Append( 's' );
         buf.Append( s.stateNumber );
         if ( AntlrTool.internalOption_ShowNFAConfigsInDFA )
         {
             if ( s is DFAState )
             {
                 if ( ( (DFAState)s ).abortedDueToRecursionOverflow )
                 {
                     buf.Append( "\\n" );
                     buf.Append( "abortedDueToRecursionOverflow" );
                 }
             }
             var alts = ( (DFAState)s ).AltSet;
             if ( alts != null )
             {
                 buf.Append( "\\n" );
                 // separate alts
                 //List altList = new ArrayList();
                 //altList.addAll( alts );
                 //Collections.sort( altList );
                 List<int> altList = alts.OrderBy( i => i ).ToList();
                 ICollection<NFAConfiguration> configurations = ( (DFAState)s ).nfaConfigurations;
                 for ( int altIndex = 0; altIndex < altList.Count; altIndex++ )
                 {
                     object altI = altList[altIndex];
                     int alt = (int)altI;
                     if ( altIndex > 0 )
                     {
                         buf.Append( "\\n" );
                     }
                     buf.Append( "alt" );
                     buf.Append( alt );
                     buf.Append( ':' );
                     // get a list of configs for just this alt
                     // it will help us print better later
                     IList configsInAlt = new List<object>();
                     foreach ( NFAConfiguration c in configurations )
                     {
                         if ( c.alt != alt )
                             continue;
                         configsInAlt.Add( c );
                     }
                     int n = 0;
                     for ( int cIndex = 0; cIndex < configsInAlt.Count; cIndex++ )
                     {
                         NFAConfiguration c =
                             (NFAConfiguration)configsInAlt[cIndex];
                         n++;
                         buf.Append( c.ToString( false ) );
                         if ( ( cIndex + 1 ) < configsInAlt.Count )
                         {
                             buf.Append( ", " );
                         }
                         if ( n % 5 == 0 && ( configsInAlt.Count - cIndex ) > 3 )
                         {
                             buf.Append( "\\n" );
                         }
                     }
                 }
             }
         }
         stateLabel = buf.ToString();
     }
     if ( ( s is NFAState ) && ( (NFAState)s ).IsDecisionState )
     {
         stateLabel = stateLabel + ",d=" +
                 ( (NFAState)s ).DecisionNumber;
         if ( ( (NFAState)s ).endOfBlockStateNumber != State.INVALID_STATE_NUMBER )
         {
             stateLabel += ",eob=" + ( (NFAState)s ).endOfBlockStateNumber;
         }
     }
     else if ( ( s is NFAState ) &&
         ( (NFAState)s ).endOfBlockStateNumber != State.INVALID_STATE_NUMBER )
     {
         NFAState n = ( (NFAState)s );
         stateLabel = stateLabel + ",eob=" + n.endOfBlockStateNumber;
     }
     else if ( s is DFAState && ( (DFAState)s ).IsAcceptState )
     {
         stateLabel = stateLabel +
                 "=>" + ( (DFAState)s ).GetUniquelyPredictedAlt();
     }
     return '"' + stateLabel + '"';
 }
예제 #3
0
 /** Return a String containing a DOT description that, when displayed,
  *  will show the incoming state machine visually.  All nodes reachable
  *  from startState will be included.
  */
 public virtual string GetDOT( State startState )
 {
     if ( startState == null )
     {
         return null;
     }
     // The output DOT graph for visualization
     StringTemplate dot = null;
     markedStates = new HashSet<int>();
     if ( startState is DFAState )
     {
         dot = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "dfa" ) );
         dot.SetAttribute( "startState",
                 startState.stateNumber );
         dot.SetAttribute( "useBox",
                          AntlrTool.internalOption_ShowNFAConfigsInDFA );
         WalkCreatingDFADOT( dot, (DFAState)startState );
     }
     else
     {
         dot = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "nfa" ) );
         dot.SetAttribute( "startState",
                 startState.stateNumber );
         WalkRuleNFACreatingDOT( dot, startState );
     }
     dot.SetAttribute( "rankdir", rankdir );
     return dot.ToString();
 }
예제 #4
0
        /** Return a String containing a DOT description that, when displayed,
         *  will show the incoming state machine visually.  All nodes reachable
         *  from startState will be included.
         */
        public string GetRuleNFADOT( State startState )
        {
            // The output DOT graph for visualization
            StringTemplate dot = GetTemplates().GetInstanceOf( "nfa" );

            markedStates = new HashSet<object>();
            dot.SetAttribute( "startState", startState.stateNumber );
            walkRuleNFACreatingDOT( dot, startState );
            return dot.Render();
        }
예제 #5
0
 /** Return a String containing a DOT description that, when displayed,
  *  will show the incoming state machine visually.  All nodes reachable
  *  from startState will be included.
  */
 public virtual string GenerateGraph( State startState )
 {
     if ( startState == null )
     {
         return null;
     }
     // The output DOT graph for visualization
     StringTemplate dot = null;
     markedStates = new HashSet<int>();
     if ( startState is DFAState )
     {
         dot = GetTemplates().GetInstanceOf( "dfa" );
         dot.SetAttribute( "startState",
                 startState.StateNumber );
         dot.SetAttribute( "useBox",
                          AntlrTool.internalOption_ShowNFAConfigsInDFA );
         WalkCreatingDFADOT( dot, (DFAState)startState );
     }
     else
     {
         dot = GetTemplates().GetInstanceOf( "nfa" );
         dot.SetAttribute( "startState",
                 startState.StateNumber );
         WalkRuleNFACreatingDOT( dot, startState );
     }
     dot.SetAttribute( "rankdir", rankdir );
     return dot.Render();
 }
예제 #6
0
 /** Given a collapsed block of alts (a set of atoms), pull out
  *  the set and return it.
  */
 protected virtual IIntSet GetCollapsedBlockAsSet( State blk )
 {
     State s0 = blk;
     if ( s0 != null && s0.GetTransition( 0 ) != null )
     {
         State s1 = s0.GetTransition( 0 ).Target;
         if ( s1 != null && s1.GetTransition( 0 ) != null )
         {
             Label label = s1.GetTransition( 0 ).Label;
             if ( label.IsSet )
             {
                 return label.Set;
             }
         }
     }
     return null;
 }
예제 #7
0
 /** Return a string representation of a state machine.  Two identical
  *  NFAs or DFAs will have identical serialized representations.  The
  *  state numbers inside the state are not used; instead, a new number
  *  is computed and because the serialization will walk the two
  *  machines using the same specific algorithm, then the state numbers
  *  will be identical.  Accept states are distinguished from regular
  *  states.
  */
 public virtual string Serialize( State s, bool renumber )
 {
     markedStates = new HashSet<State>();
     stateCounter = 0;
     if ( renumber )
     {
         stateNumberTranslator = new Dictionary<State, int>();
         WalkFANormalizingStateNumbers( s );
     }
     List<string> lines = new List<string>();
     if ( s.NumberOfTransitions > 0 )
     {
         WalkSerializingFA( lines, s );
     }
     else
     {
         // special case: s0 is an accept
         string s0 = GetStateString( 0, s );
         lines.Add( s0 + "\n" );
     }
     StringBuilder buf = new StringBuilder( 0 );
     // sort lines to normalize; makes states come out ordered
     // and then ordered by edge labels then by target state number :)
     lines.Sort( System.StringComparer.Ordinal );
     for ( int i = 0; i < lines.Count; i++ )
     {
         string line = (string)lines[i];
         buf.Append( line );
     }
     return buf.ToString();
 }
예제 #8
0
        private string GetStateLabel(State state)
        {
            if (state == null)
                return "null";

            string stateLabel = state.StateNumber.ToString();
            DFAState dfaState = state as DFAState;
            NFAState nfaState = state as NFAState;
            if (dfaState != null)
            {
                StringBuilder builder = new StringBuilder(250);
                builder.Append('s');
                builder.Append(state.StateNumber);
                if (AntlrTool.internalOption_ShowNFAConfigsInDFA)
                {
                    if (dfaState.AbortedDueToRecursionOverflow)
                    {
                        builder.AppendLine();
                        builder.AppendLine("AbortedDueToRecursionOverflow");
                    }

                    var alts = dfaState.AltSet;
                    if (alts != null)
                    {
                        builder.AppendLine();
                        List<int> altList = alts.OrderBy(i => i).ToList();
                        ICollection<NFAConfiguration> configurations = dfaState.NfaConfigurations;
                        for (int i = 0; i < altList.Count; i++)
                        {
                            int alt = altList[i];
                            if (i > 0)
                                builder.AppendLine();
                            builder.AppendFormat("alt{0}:", alt);
                            // get a list of configs for just this alt
                            // it will help us print better later
                            List<NFAConfiguration> configsInAlt = new List<NFAConfiguration>();
                            foreach (NFAConfiguration c in configurations)
                            {
                                if (c.Alt != alt)
                                    continue;

                                configsInAlt.Add(c);
                            }

                            int n = 0;
                            for (int cIndex = 0; cIndex < configsInAlt.Count; cIndex++)
                            {
                                NFAConfiguration c = configsInAlt[cIndex];
                                n++;
                                builder.Append(c.ToString(false));
                                if ((cIndex + 1) < configsInAlt.Count)
                                {
                                    builder.Append(", ");
                                }
                                if (n % 5 == 0 && (configsInAlt.Count - cIndex) > 3)
                                {
                                    builder.Append("\\n");
                                }
                            }
                        }
                    }
                }

                if (dfaState.IsAcceptState)
                {
                    builder.Append("⇒" + dfaState.GetUniquelyPredictedAlt());
                }

                stateLabel = builder.ToString();
            }
            else if (nfaState != null)
            {
                if (nfaState.IsDecisionState)
                    stateLabel += ",d=" + nfaState.DecisionNumber;

                if (nfaState.endOfBlockStateNumber != State.INVALID_STATE_NUMBER)
                    stateLabel += ",eob=" + nfaState.endOfBlockStateNumber;
            }

            return stateLabel;
        }
예제 #9
0
 private string GetStateString( int n, State s )
 {
     string stateStr = ".s" + n;
     if ( s.IsAcceptState )
     {
         if ( s is DFAState )
         {
             stateStr = ":s" + n + "=>" + ( (DFAState)s ).GetUniquelyPredictedAlt();
         }
         else
         {
             stateStr = ":s" + n;
         }
     }
     return stateStr;
 }
예제 #10
0
        protected virtual void WalkSerializingFA( IList lines, State s )
        {
            if ( markedStates.Contains( s ) )
            {
                return; // already visited this node
            }

            markedStates.Add( s ); // mark this node as completed.

            int normalizedStateNumber = s.stateNumber;
            if ( stateNumberTranslator != null )
            {
                normalizedStateNumber = stateNumberTranslator[s];
            }

            string stateStr = GetStateString( normalizedStateNumber, s );

            // depth first walk each transition, printing its edge first
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition edge = (Transition)s.GetTransition( i );
                StringBuilder buf = new StringBuilder();
                buf.Append( stateStr );
                if ( edge.IsAction )
                {
                    buf.Append( "-{}->" );
                }
                else if ( edge.IsEpsilon )
                {
                    buf.Append( "->" );
                }
                else if ( edge.IsSemanticPredicate )
                {
                    buf.Append( "-{" + edge.label.SemanticContext + "}?->" );
                }
                else
                {
                    string predsStr = "";
                    if ( edge.target is DFAState )
                    {
                        // look for gated predicates; don't add gated to simple sempred edges
                        SemanticContext preds =
                            ( (DFAState)edge.target ).GetGatedPredicatesInNFAConfigurations();
                        if ( preds != null )
                        {
                            predsStr = "&&{" +
                                preds.GenExpr( grammar.generator,
                                              grammar.generator.Templates, null ).ToString()
                                + "}?";
                        }
                    }
                    buf.Append( "-" + edge.label.ToString( grammar ) + predsStr + "->" );
                }

                int normalizedTargetStateNumber = edge.target.stateNumber;
                if ( stateNumberTranslator != null )
                {
                    normalizedTargetStateNumber = stateNumberTranslator[edge.target];
                }
                buf.Append( GetStateString( normalizedTargetStateNumber, edge.target ) );
                buf.Append( "\n" );
                lines.Add( buf.ToString() );

                // walk this transition
                WalkSerializingFA( lines, edge.target );

                // if this transition is a rule reference, the node "following" this state
                // will not be found and appear to be not in graph.  Must explicitly jump
                // to it, but don't "draw" an edge.
                if ( edge is RuleClosureTransition )
                {
                    WalkSerializingFA( lines, ( (RuleClosureTransition)edge ).followState );
                }
            }
        }
예제 #11
0
        /** In stateNumberTranslator, get a map from State to new, normalized
         *  state number.  Used by walkSerializingFA to make sure any two
         *  identical state machines will serialize the same way.
         */
        protected virtual void WalkFANormalizingStateNumbers( State s )
        {
            if ( s == null )
            {
                ErrorManager.InternalError( "null state s" );
                return;
            }
            if ( stateNumberTranslator.ContainsKey( s ) )
            {
                return; // already did this state
            }
            // assign a new state number for this node if there isn't one
            stateNumberTranslator[s] = stateCounter;
            stateCounter++;

            // visit nodes pointed to by each transition;
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition edge = (Transition)s.GetTransition( i );
                WalkFANormalizingStateNumbers( edge.target ); // keep walkin'
                // if this transition is a rule reference, the node "following" this state
                // will not be found and appear to be not in graph.  Must explicitly jump
                // to it, but don't "draw" an edge.
                if ( edge is RuleClosureTransition )
                {
                    WalkFANormalizingStateNumbers( ( (RuleClosureTransition)edge ).followState );
                }
            }
        }
예제 #12
0
        public string GenerateGraph(State state)
        {
            _nodes.Clear();
            _links.Clear();
            _extraNodes.Clear();
            _extraLinks.Clear();
            _markedStates.Clear();
            _canSkipStates.Clear();

            DFAState dfaState = state as DFAState;
            if (GroupNodes)
            {
                if (dfaState != null)
                {
                    _groupId = "decision_";
                    _extraNodes.Add(new XElement(Elements.Node,
                        new XAttribute(Attributes.Id, _groupId),
                        new XAttribute(Attributes.Label, dfaState.StateNumber.ToString()),
                        new XAttribute(Attributes.Group, "Collapsed")));
                }
                else
                {
                    NFAState nfaState = (NFAState)state;
                    _groupId = "rule_" + nfaState.enclosingRule.Name;
                    _extraNodes.Add(new XElement(Elements.Node,
                        new XAttribute(Attributes.Id, _groupId),
                        new XAttribute(Attributes.Label, nfaState.enclosingRule.Name),
                        new XAttribute(Attributes.Group, "Collapsed")));
                }
            }

            if (dfaState != null)
            {
                WalkCreatingDfaDgml(dfaState);
            }
            else
            {
                WalkRuleNfaCreatingDgml(state);
                LocateVerboseStates(state);
            }

            XDocument document = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XElement(Elements.DirectedGraph,
                    new XAttribute(Attributes.GraphDirection, GraphDirection.TopToBottom),
                    new XAttribute(Attributes.Layout, Layout.Sugiyama),
                    GetNodes(),
                    GetLinks(),
                    GetCategories(),
                    GetProperties(),
                    GetStyles()));

            return document.ToString();
        }
예제 #13
0
        private void WalkRuleNfaCreatingDgml(State state)
        {
            if (!_markedStates.Add(state.StateNumber))
                return;

            NFAState nfaState = state as NFAState;

            // create the node
            string nodeCategory;
            if (state.IsAcceptState)
                nodeCategory = Categories.StopState;
            else if (nfaState != null && nfaState.IsDecisionState)
                nodeCategory = Categories.DecisionState;
            else
                nodeCategory = Categories.State;

            XElement node = new XElement(Elements.Node,
                new XAttribute(Attributes.Id, "state_" + state.StateNumber),
                new XAttribute(Attributes.Label, GetStateLabel(state)),
                new XAttribute(Attributes.Category, nodeCategory));

            if (nfaState != null && nfaState.IsDecisionState)
            {
                string baseFileName = _grammar.name;
                if (_grammar.implicitLexer)
                    baseFileName += Grammar.grammarTypeToFileNameSuffix[(int)_grammar.type];

                string decisionPath = string.Format("{0}.dec-{1}.dgml", baseFileName, nfaState.DecisionNumber);
                node.Add(new XAttribute(Attributes.Reference, decisionPath));
            }

            _nodes.Add(state, node);
            if (GroupNodes)
                _extraLinks.Add(CreateContainmentLink(_groupId, "state_" + state.StateNumber));

            // don't go past end of rule
            if (state.IsAcceptState)
                return;

            // create links for each transition
            for (int i = 0; i < state.NumberOfTransitions; i++)
            {
                Transition edge = state.GetTransition(i);
                RuleClosureTransition rr = edge as RuleClosureTransition;
                if (rr != null)
                {
                    string label;

                    if (rr.Rule.Grammar != _grammar)
                        label = string.Format("<{0}.{1}>", rr.Rule.Grammar.name, rr.Rule.Name);
                    else
                        label = string.Format("<{0}>", rr.Rule.Name);

                    XElement link = new XElement(Elements.Link,
                        new XAttribute(Attributes.Source, "state_" + state.StateNumber),
                        new XAttribute(Attributes.Target, "state_" + rr.FollowState),
                        new XAttribute(Attributes.Category, Categories.RuleClosureEdge),
                        new XAttribute(Attributes.Label, label));

                    _links.Add(new KeyValuePair<State, Transition>(state, edge), link);
                    WalkRuleNfaCreatingDgml(rr.FollowState);
                }
                else
                {
                    string edgeCategory;

                    if (edge.IsAction)
                        edgeCategory = Categories.ActionEdge;
                    else if (edge.IsEpsilon)
                        edgeCategory = Categories.EpsilonEdge;
                    else if (edge.Label.IsSet || edge.Label.IsAtom)
                        edgeCategory = Categories.AtomEdge;
                    else
                        edgeCategory = Categories.Edge;

                    XElement link = new XElement(Elements.Link,
                        new XAttribute(Attributes.Source, "state_" + state.StateNumber),
                        new XAttribute(Attributes.Target, "state_" + edge.Target.StateNumber),
                        new XAttribute(Attributes.Category, edgeCategory),
                        new XAttribute(Attributes.Label, GetEdgeLabel(edge)));

                    _links.Add(new KeyValuePair<State, Transition>(state, edge), link);
                    WalkRuleNfaCreatingDgml(edge.Target);
                }
            }
        }
예제 #14
0
        private void LocateVerboseStates(State startState)
        {
            Dictionary<State, XElement> verboseNodes = _nodes.Where(IsVerboseNode).ToDictionary(i => i.Key, i => i.Value);
            verboseNodes.Remove(startState);

            foreach (var verboseNode in verboseNodes)
            {
                verboseNode.Value.Add(new XElement(Elements.Category,
                    new XAttribute(Attributes.Ref, Categories.VerboseNode)));
            }

            Dictionary<State, List<State>> shortcuts = new Dictionary<State, List<State>>();
            foreach (var link in _links)
            {
                State source = link.Key.Key;
                State target = link.Key.Value.Target;
                if (!verboseNodes.ContainsKey(source) && verboseNodes.ContainsKey(target))
                {
                    List<State> newTargets = new List<State>();
                    Stack<State> remaining = new Stack<State>();
                    remaining.Push(target);
                    while (remaining.Count > 0)
                    {
                        State current = remaining.Pop();
                        if (!verboseNodes.ContainsKey(current))
                        {
                            if (_nodes.ContainsKey(current))
                                newTargets.Add(current);
                        }
                        else
                        {
                            for (int i = 0; i < current.NumberOfTransitions; i++)
                            {
                                remaining.Push(current.GetTransition(i).Target);
                            }
                        }
                    }

                    foreach (var newTarget in newTargets)
                    {
                        XElement newLink = new XElement(link.Value);
                        newLink.Attribute(Attributes.Target).Remove();
                        newLink.Add(new XAttribute(Attributes.Target, "state_" + newTarget.StateNumber));
                        newLink.Add(new XElement(Elements.Category, new XAttribute(Attributes.Ref, Categories.OptimizedEdge)));

                        _extraLinks.Add(newLink);
                    }
                }
            }
        }
예제 #15
0
        /** Do a depth-first walk of the state machine graph and
         *  fill a DOT description template.  Keep filling the
         *  states and edges attributes.  We know this is an NFA
         *  for a rule so don't traverse edges to other rules and
         *  don't go past rule end state.
         */
        protected virtual void WalkRuleNFACreatingDOT( StringTemplate dot,
                                              State s )
        {
            if ( markedStates.Contains( s.stateNumber ) )
            {
                return; // already visited this node
            }

            markedStates.Add( s.stateNumber ); // mark this node as completed.

            // first add this node
            StringTemplate stateST;
            if ( s.IsAcceptState )
            {
                stateST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "stopstate" ) );
            }
            else
            {
                stateST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "state" ) );
            }
            stateST.SetAttribute( "name", GetStateLabel( s ) );
            dot.SetAttribute( "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.Type != ANTLRParser.EOB )
                {
                    StringTemplate rankST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "decision-rank" ) );
                    NFAState alt = (NFAState)s;
                    while ( alt != null )
                    {
                        rankST.SetAttribute( "states", GetStateLabel( alt ) );
                        if ( alt.transition[1] != null )
                        {
                            alt = (NFAState)alt.transition[1].target;
                        }
                        else
                        {
                            alt = null;
                        }
                    }
                    dot.SetAttribute( "decisionRanks", rankST );
                }
            }

            // make a DOT edge for each transition
            StringTemplate edgeST = null;
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition edge = (Transition)s.GetTransition( i );
                if ( edge is RuleClosureTransition )
                {
                    RuleClosureTransition rr = ( (RuleClosureTransition)edge );
                    // don't jump to other rules, but display edge to follow node
                    edgeST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "edge" ) );
                    if ( rr.rule.grammar != grammar )
                    {
                        edgeST.SetAttribute( "label", "<" + rr.rule.grammar.name + "." + rr.rule.Name + ">" );
                    }
                    else
                    {
                        edgeST.SetAttribute( "label", "<" + rr.rule.Name + ">" );
                    }
                    edgeST.SetAttribute( "src", GetStateLabel( s ) );
                    edgeST.SetAttribute( "target", GetStateLabel( rr.followState ) );
                    edgeST.SetAttribute( "arrowhead", arrowhead );
                    dot.SetAttribute( "edges", edgeST );
                    WalkRuleNFACreatingDOT( dot, rr.followState );
                    continue;
                }
                if ( edge.IsAction )
                {
                    edgeST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "action-edge" ) );
                }
                else if ( edge.IsEpsilon )
                {
                    edgeST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "epsilon-edge" ) );
                }
                else
                {
                    edgeST = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "edge" ) );
                }
                edgeST.SetAttribute( "label", GetEdgeLabel( edge ) );
                edgeST.SetAttribute( "src", GetStateLabel( s ) );
                edgeST.SetAttribute( "target", GetStateLabel( edge.target ) );
                edgeST.SetAttribute( "arrowhead", arrowhead );
                dot.SetAttribute( "edges", edgeST );
                WalkRuleNFACreatingDOT( dot, edge.target ); // keep walkin'
            }
        }
예제 #16
0
        /** Return a String containing a DOT description that, when displayed,
         *  will show the incoming state machine visually.  All nodes reachable
         *  from startState will be included.
         */
        public string GetRuleNFADOT( State startState )
        {
            // The output DOT graph for visualization
            StringTemplate dot = stlib.GetInstanceOf( Path.Combine( dfaTemplateDirectoryName, "nfa" ) );

            markedStates = new HashSet<object>();
            dot.SetAttribute( "startState", startState.stateNumber );
            walkRuleNFACreatingDOT( dot, startState );
            return dot.ToString();
        }
예제 #17
0
        /** Given a start state and a final state, find a list of edge labels
         *  between the two ignoring epsilon.  Limit your scan to a set of states
         *  passed in.  This is used to show a sample input sequence that is
         *  nondeterministic with respect to this decision.  Return IList<Label> as
         *  a parameter.  The incoming states set must be all states that lead
         *  from startState to targetState and no others so this algorithm doesn't
         *  take a path that eventually leads to a state other than targetState.
         *  Don't follow loops, leading to short (possibly shortest) path.
         */
        protected virtual void GetSampleInputSequenceUsingStateSet( State startState,
                                                           State targetState,
                                                           HashSet<object> states,
                                                           IList<Label> labels )
        {
            _statesVisitedDuringSampleSequence.Add( startState.StateNumber );

            // pick the first edge in states as the one to traverse
            for ( int i = 0; i < startState.NumberOfTransitions; i++ )
            {
                Transition t = startState.GetTransition( i );
                DFAState edgeTarget = (DFAState)t.Target;
                if ( states.Contains( edgeTarget ) &&
                     !_statesVisitedDuringSampleSequence.Contains( edgeTarget.StateNumber ) )
                {
                    labels.Add( t.Label ); // traverse edge and track label
                    if ( edgeTarget != targetState )
                    {
                        // get more labels if not at target
                        GetSampleInputSequenceUsingStateSet( edgeTarget,
                                                            targetState,
                                                            states,
                                                            labels );
                    }
                    // done with this DFA state as we've found a good path to target
                    return;
                }
            }
            labels.Add( new Label( Label.EPSILON ) ); // indicate no input found
            // this happens on a : {p1}? a | A ;
            //ErrorManager.error(ErrorManager.MSG_CANNOT_COMPUTE_SAMPLE_INPUT_SEQ);
        }