GetUniquelyPredictedAlt() public method

public GetUniquelyPredictedAlt ( ) : int
return int
Example #1
0
        protected virtual void OptimizeExitBranches(DFAState d)
        {
            int sI = d.stateNumber;

            if (_visited.Contains(sI))
            {
                return; // already visited
            }
            _visited.Add(sI);
            int nAlts = d.dfa.NumberOfAlts;

            for (int i = 0; i < d.NumberOfTransitions; i++)
            {
                Transition edge       = (Transition)d.Transition(i);
                DFAState   edgeTarget = ((DFAState)edge.target);

                /*
                 * [email protected](d.stateNumber+"-"+
                 *                 edge.label.toString(d.dfa.nfa.grammar)+"->"+
                 *                 edgeTarget.stateNumber);
                 */
                // if target is an accept state and that alt is the exit alt
                if (edgeTarget.IsAcceptState &&
                    edgeTarget.GetUniquelyPredictedAlt() == nAlts)
                {
                    /*
                     * [email protected]("ignoring transition "+i+" to max alt "+
                     *  d.dfa.getNumberOfAlts());
                     */
                    d.RemoveTransition(i);
                    i--; // back up one so that i++ of loop iteration stays within bounds
                }
                OptimizeExitBranches(edgeTarget);
            }
        }
Example #2
0
        protected virtual void OptimizeEOTBranches(DFAState state)
        {
            if (state == null)
            {
                throw new ArgumentNullException("state");
            }

            int sI = state.StateNumber;

            if (_visited.Contains(sI))
            {
                return; // already visited
            }
            _visited.Add(sI);
            for (int i = 0; i < state.NumberOfTransitions; i++)
            {
                Transition edge       = state.GetTransition(i);
                DFAState   edgeTarget = ((DFAState)edge.Target);

                /*
                 * [email protected](d.stateNumber+"-"+
                 *                 edge.label.toString(d.dfa.nfa.grammar)+"->"+
                 *                 edgeTarget.stateNumber);
                 */
                // if only one edge coming out, it is EOT, and target is accept prune
                if (PRUNE_TOKENS_RULE_SUPERFLUOUS_EOT_EDGES &&
                    edgeTarget.IsAcceptState &&
                    state.NumberOfTransitions == 1 &&
                    edge.Label.IsAtom &&
                    edge.Label.Atom == Label.EOT)
                {
                    //[email protected]("state "+d+" can be pruned");
                    // remove the superfluous EOT edge
                    state.RemoveTransition(i);
                    state.IsAcceptState = true; // make it an accept state
                    // force it to uniquely predict the originally predicted state
                    state.CachedUniquelyPredicatedAlt = edgeTarget.GetUniquelyPredictedAlt();
                    i--; // back up one so that i++ of loop iteration stays within bounds
                }
                OptimizeEOTBranches(edgeTarget);
            }
        }
Example #3
0
        /** figure out if this state eventually reaches an accept state and
         *  modify the instance variable 'reduced' to indicate if we find
         *  at least one state that cannot reach an accept state.  This implies
         *  that the overall DFA is not reduced.  This algorithm should be
         *  linear in the number of DFA states.
         *
         *  The algorithm also tracks which alternatives have no accept state,
         *  indicating a nondeterminism.
         *
         *  Also computes whether the DFA is cyclic.
         *
         *  TODO: I call getUniquelyPredicatedAlt too much; cache predicted alt
         */
        protected virtual bool DoesStateReachAcceptState( DFAState d )
        {
            if ( d.IsAcceptState )
            {
                // accept states have no edges emanating from them so we can return
                d.AcceptStateReachable = Reachable.Yes;
                // this alt is uniquely predicted, remove from nondeterministic list
                int predicts = d.GetUniquelyPredictedAlt();
                UnreachableAlts.Remove( predicts );
                return true;
            }

            // avoid infinite loops
            d.AcceptStateReachable = Reachable.Busy;

            bool anEdgeReachesAcceptState = false;
            // Visit every transition, track if at least one edge reaches stop state
            // Cannot terminate when we know this state reaches stop state since
            // all transitions must be traversed to set status of each DFA state.
            for ( int i = 0; i < d.NumberOfTransitions; i++ )
            {
                Transition t = d.GetTransition( i );
                DFAState edgeTarget = (DFAState)t.Target;
                Reachable targetStatus = edgeTarget.AcceptStateReachable;
                if ( targetStatus == Reachable.Busy )
                {
                    // avoid cycles; they say nothing
                    _cyclic = true;
                    continue;
                }

                if ( targetStatus == Reachable.Yes )
                {
                    // avoid unnecessary work
                    anEdgeReachesAcceptState = true;
                    continue;
                }

                if ( targetStatus == Reachable.No )
                {
                    // avoid unnecessary work
                    continue;
                }

                // target must be REACHABLE_UNKNOWN (i.e., unvisited)
                if ( DoesStateReachAcceptState( edgeTarget ) )
                {
                    anEdgeReachesAcceptState = true;
                    // have to keep looking so don't break loop
                    // must cover all states even if we find a path for this state
                }
            }

            if ( anEdgeReachesAcceptState )
            {
                d.AcceptStateReachable = Reachable.Yes;
            }
            else
            {
                d.AcceptStateReachable = Reachable.No;
                _reduced = false;
            }

            return anEdgeReachesAcceptState;
        }
        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;
        }