Пример #1
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.GetTransition(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());
        }
Пример #2
0
        protected virtual StringTemplate WalkFixedDFAGeneratingStateMachine(
            TemplateGroup 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.GetTransition(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.impl.TryGetFormalArgument("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.GetTransition(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);
        }
Пример #3
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);
        }