Exemplo n.º 1
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);
        }
Exemplo n.º 2
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'
            }
        }
Exemplo n.º 3
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 );
                }
            }
        }
Exemplo n.º 4
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 );
                }
            }
        }
Exemplo n.º 5
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);
                }
            }
        }
Exemplo n.º 6
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);
        }