Пример #1
0
        private void WalkCreatingDfaDgml(DFAState dfaState)
        {
            if (!_markedStates.Add(dfaState.stateNumber))
            {
                return;
            }

            // first add this node
            string nodeCategory;

            if (dfaState.IsAcceptState)
            {
                nodeCategory = Categories.StopState;
            }
            else
            {
                nodeCategory = Categories.State;
            }

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

            _nodes.Add(dfaState, node);
            if (GroupNodes)
            {
                _extraLinks.Add(CreateContainmentLink(_groupId, "state_" + dfaState.stateNumber));
            }

            // make an edge for each transition
            for (int i = 0; i < dfaState.NumberOfTransitions; i++)
            {
                Transition edge = dfaState.Transition(i);
                if (StripNonreducedStates)
                {
                    DFAState target = edge.target as DFAState;
                    // don't generate nodes for terminal states
                    if (target != null && target.AcceptStateReachable != DFA.REACHABLE_YES)
                    {
                        continue;
                    }
                }

                string   edgeCategory = Categories.Edge;
                XElement edgeElement  = new XElement(Elements.Link,
                                                     new XAttribute(Attributes.Source, "state_" + dfaState.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>(dfaState, edge), edgeElement);
                WalkCreatingDfaDgml((DFAState)edge.Target);
            }
        }
Пример #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.
         */
        protected virtual void WalkCreatingDFADOT(StringTemplate dot,
                                                  DFAState 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 st;

            if (s.IsAcceptState)
            {
                st = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "stopstate"));
            }
            else
            {
                st = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "state"));
            }
            st.SetAttribute("name", GetStateLabel(s));
            dot.SetAttribute("states", st);

            // make a DOT edge for each transition
            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition edge = (Transition)s.Transition(i);
                //Console.Out.WriteLine( "dfa " + s.dfa.decisionNumber + " edge from s"
                //    + s.stateNumber + " [" + i + "] of " + s.NumberOfTransitions );
                if (StripNonreducedStates)
                {
                    if (edge.target is DFAState &&
                        ((DFAState)edge.target).AcceptStateReachable != DFA.REACHABLE_YES)
                    {
                        continue; // don't generate nodes for terminal states
                    }
                }
                st = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "edge"));
                st.SetAttribute("label", GetEdgeLabel(edge));
                st.SetAttribute("src", GetStateLabel(s));
                st.SetAttribute("target", GetStateLabel(edge.target));
                st.SetAttribute("arrowhead", arrowhead);
                dot.SetAttribute("edges", st);
                WalkCreatingDFADOT(dot, (DFAState)edge.target);   // keep walkin'
            }
        }
Пример #3
0
        /** Given an input stream, return the unique alternative predicted by
         *  matching the input.  Upon error, return NFA.INVALID_ALT_NUMBER
         *  The first symbol of lookahead is presumed to be primed; that is,
         *  input.lookahead(1) must point at the input symbol you want to start
         *  predicting with.
         */
        public int Predict(DFA dfa)
        {
            DFAState   s             = dfa.startState;
            int        c             = input.LA(1);
            Transition eotTransition = null;

dfaLoop:
            while (!s.IsAcceptState)
            {
                //Console.Out.WriteLine( "DFA.predict(" + s.stateNumber + ", " + dfa.nfa.grammar.getTokenDisplayName( c ) + ")" );
                // for each edge of s, look for intersection with current char
                for (int i = 0; i < s.NumberOfTransitions; i++)
                {
                    Transition t = s.Transition(i);
                    // special case: EOT matches any char
                    if (t.label.Matches(c))
                    {
                        // take transition i
                        s = (DFAState)t.target;
                        input.Consume();
                        c = input.LA(1);
                        goto dfaLoop;
                    }
                    if (t.label.Atom == Label.EOT)
                    {
                        eotTransition = t;
                    }
                }
                if (eotTransition != null)
                {
                    s = (DFAState)eotTransition.target;
                    goto dfaLoop;
                }

                /*
                 * ErrorManager.error(ErrorManager.MSG_NO_VIABLE_DFA_ALT,
                 *                 s,
                 *                 dfa.nfa.grammar.getTokenName(c));
                 */
                return(NFA.INVALID_ALT_NUMBER);
            }
            // woohoo!  We know which alt to predict
            // nothing emanates from a stop state; must terminate anyway
            //Console.Out.WriteLine( "DFA stop state " + s.stateNumber + " predicts " + s.getUniquelyPredictedAlt() );
            return(s.GetUniquelyPredictedAlt());
        }
Пример #4
0
        protected virtual StringTemplate WalkFixedDFAGeneratingStateMachine(
            StringTemplateGroup templates,
            DFA dfa,
            DFAState s,
            int k)
        {
            //System.Console.Out.WriteLine( "walk " + s.stateNumber + " in dfa for decision " + dfa.decisionNumber );
            if (s.IsAcceptState)
            {
                StringTemplate dfaST2 = templates.GetInstanceOf("dfaAcceptState");
                dfaST2.SetAttribute("alt", s.GetUniquelyPredictedAlt());
                return(dfaST2);
            }

            // the default templates for generating a state and its edges
            // can be an if-then-else structure or a switch
            string dfaStateName              = "dfaState";
            string dfaLoopbackStateName      = "dfaLoopbackState";
            string dfaOptionalBlockStateName = "dfaOptionalBlockState";
            string dfaEdgeName = "dfaEdge";

            if (parentGenerator.CanGenerateSwitch(s))
            {
                dfaStateName              = "dfaStateSwitch";
                dfaLoopbackStateName      = "dfaLoopbackStateSwitch";
                dfaOptionalBlockStateName = "dfaOptionalBlockStateSwitch";
                dfaEdgeName = "dfaEdgeSwitch";
            }

            StringTemplate dfaST = templates.GetInstanceOf(dfaStateName);

            if (dfa.NFADecisionStartState.decisionStateType == NFAState.LOOPBACK)
            {
                dfaST = templates.GetInstanceOf(dfaLoopbackStateName);
            }
            else if (dfa.NFADecisionStartState.decisionStateType == NFAState.OPTIONAL_BLOCK_START)
            {
                dfaST = templates.GetInstanceOf(dfaOptionalBlockStateName);
            }
            dfaST.SetAttribute("k", k);
            dfaST.SetAttribute("stateNumber", s.stateNumber);
            dfaST.SetAttribute("semPredState",
                               s.IsResolvedWithPredicates);

            /*
             * string description = dfa.getNFADecisionStartState().Description;
             * description = parentGenerator.target.getTargetStringLiteralFromString( description );
             * //System.Console.Out.WriteLine( "DFA: " + description + " associated with AST " + dfa.getNFADecisionStartState() );
             * if ( description != null )
             * {
             *  dfaST.SetAttribute( "description", description );
             * }
             */
            int      EOTPredicts = NFA.INVALID_ALT_NUMBER;
            DFAState EOTTarget   = null;

            //System.Console.Out.WriteLine( "DFA state " + s.stateNumber );
            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition edge = (Transition)s.Transition(i);
                //System.Console.Out.WriteLine( "edge " + s.stateNumber + "-" + edge.label.ToString() + "->" + edge.target.stateNumber );
                if (edge.label.Atom == Label.EOT)
                {
                    // don't generate a real edge for EOT; track alt EOT predicts
                    // generate that prediction in the else clause as default case
                    EOTTarget   = (DFAState)edge.target;
                    EOTPredicts = EOTTarget.GetUniquelyPredictedAlt();

                    /*
                     * System.Console.Out.WriteLine("DFA s"+s.stateNumber+" EOT goes to s"+
                     *                 edge.target.stateNumber+" predicates alt "+
                     *                 EOTPredicts);
                     */
                    continue;
                }
                StringTemplate edgeST = templates.GetInstanceOf(dfaEdgeName);
                // If the template wants all the label values delineated, do that
                if (edgeST.GetFormalArgument("labels") != null)
                {
                    List <string> labels = edge.Label.Set.Select(value => parentGenerator.GetTokenTypeAsTargetLabel(value)).ToList();
                    edgeST.SetAttribute("labels", labels);
                }
                else
                { // else create an expression to evaluate (the general case)
                    edgeST.SetAttribute("labelExpr",
                                        parentGenerator.GenLabelExpr(templates, edge, k));
                }

                // stick in any gated predicates for any edge if not already a pred
                if (!edge.label.IsSemanticPredicate)
                {
                    DFAState        target = (DFAState)edge.target;
                    SemanticContext preds  =
                        target.GetGatedPredicatesInNFAConfigurations();
                    if (preds != null)
                    {
                        //System.Console.Out.WriteLine( "preds=" + target.getGatedPredicatesInNFAConfigurations() );
                        StringTemplate predST = preds.GenExpr(parentGenerator,
                                                              parentGenerator.Templates,
                                                              dfa);
                        edgeST.SetAttribute("predicates", predST);
                    }
                }

                StringTemplate targetST =
                    WalkFixedDFAGeneratingStateMachine(templates,
                                                       dfa,
                                                       (DFAState)edge.target,
                                                       k + 1);
                edgeST.SetAttribute("targetState", targetST);
                dfaST.SetAttribute("edges", edgeST);
                //System.Console.Out.WriteLine( "back to DFA " + dfa.decisionNumber + "." + s.stateNumber );
            }

            // HANDLE EOT EDGE
            if (EOTPredicts != NFA.INVALID_ALT_NUMBER)
            {
                // EOT unique predicts an alt
                dfaST.SetAttribute("eotPredictsAlt", EOTPredicts);
            }
            else if (EOTTarget != null && EOTTarget.NumberOfTransitions > 0)
            {
                // EOT state has transitions so must split on predicates.
                // Generate predicate else-if clauses and then generate
                // NoViableAlt exception as else clause.
                // Note: these predicates emanate from the EOT target state
                // rather than the current DFAState s so the error message
                // might be slightly misleading if you are looking at the
                // state number.  Predicates emanating from EOT targets are
                // hoisted up to the state that has the EOT edge.
                for (int i = 0; i < EOTTarget.NumberOfTransitions; i++)
                {
                    Transition     predEdge = (Transition)EOTTarget.Transition(i);
                    StringTemplate edgeST   = templates.GetInstanceOf(dfaEdgeName);
                    edgeST.SetAttribute("labelExpr",
                                        parentGenerator.GenSemanticPredicateExpr(templates, predEdge));
                    // the target must be an accept state
                    //System.Console.Out.WriteLine( "EOT edge" );
                    StringTemplate targetST =
                        WalkFixedDFAGeneratingStateMachine(templates,
                                                           dfa,
                                                           (DFAState)predEdge.target,
                                                           k + 1);
                    edgeST.SetAttribute("targetState", targetST);
                    dfaST.SetAttribute("edges", edgeST);
                }
            }
            return(dfaST);
        }