Inheritance: Antlr3.Analysis.State
Beispiel #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);
            }
        }
Beispiel #2
0
        public List <DFAState> GetAnyDFAPathToTarget(DFAState startState, DFAState targetState, HashSet <DFAState> visited)
        {
            List <DFAState> dfaStates = new List <DFAState>();

            visited.Add(startState);
            if (startState.Equals(targetState))
            {
                dfaStates.Add(targetState);
                return(dfaStates);
            }
            // for (Edge e : startState.edges) { // walk edges looking for valid
            // path
            for (int i = 0; i < startState.NumberOfTransitions; i++)
            {
                Transition e = startState.GetTransition(i);
                if (!visited.Contains((DFAState)e.Target))
                {
                    List <DFAState> path = GetAnyDFAPathToTarget((DFAState)e.target, targetState, visited);
                    if (path != null)
                    { // found path, we're done
                        dfaStates.Add(startState);
                        dfaStates.AddRange(path);
                        return(dfaStates);
                    }
                }
            }
            return(null);
        }
Beispiel #3
0
        /** Report the list of predicates found for each alternative; copy
         *  the list because this set gets altered later by the method
         *  tryToResolveWithSemanticPredicates() while flagging NFA configurations
         *  in d as resolved.
         */
        public virtual void ReportAltPredicateContext(DFAState d, IDictionary <int, SemanticContext> altPredicateContext)
        {
            IDictionary <int, SemanticContext> copy = new Dictionary <int, SemanticContext>(altPredicateContext);

            //copy.putAll( altPredicateContext );
            _stateToAltSetWithSemanticPredicatesMap[d] = copy;
        }
Beispiel #4
0
        /** Two DFAStates are equal if their NFA configuration sets are the
         *  same. This method is used to see if a DFA state already exists.
         *
         *  Because the number of alternatives and number of NFA configurations are
         *  finite, there is a finite number of DFA states that can be processed.
         *  This is necessary to show that the algorithm terminates.
         *
         *  Cannot test the DFA state numbers here because in DFA.addState we need
         *  to know if any other state exists that has this exact set of NFA
         *  configurations.  The DFAState state number is irrelevant.
         */
        public override bool Equals(object o)
        {
            // compare set of NFA configurations in this set with other
            DFAState other = o as DFAState;

            if (other == null)
            {
                return(false);
            }

            if (object.ReferenceEquals(_nfaConfigurations, other._nfaConfigurations))
            {
                return(true);
            }

            if (this._nfaConfigurations.Equals(other._nfaConfigurations))
            {
                return(true);
            }

            if (_nfaConfigurations.SequenceEqual(other._nfaConfigurations))
            {
                return(true);
            }

            return(false);
        }
Beispiel #5
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&lt;Label&gt; 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);
        }
Beispiel #6
0
 public List<DFAState> GetAnyDFAPathToTarget(DFAState startState, DFAState targetState, HashSet<DFAState> visited)
 {
     List<DFAState> dfaStates = new List<DFAState>();
     visited.Add(startState);
     if (startState.Equals(targetState))
     {
         dfaStates.Add(targetState);
         return dfaStates;
     }
     // for (Edge e : startState.edges) { // walk edges looking for valid
     // path
     for (int i = 0; i < startState.NumberOfTransitions; i++)
     {
         Transition e = startState.GetTransition(i);
         if (!visited.Contains((DFAState)e.Target))
         {
             List<DFAState> path = GetAnyDFAPathToTarget((DFAState)e.Target, targetState, visited);
             if (path != null)
             { // found path, we're done
                 dfaStates.Add(startState);
                 dfaStates.AddRange(path);
                 return dfaStates;
             }
         }
     }
     return null;
 }
Beispiel #7
0
 public virtual void ReportNondeterminism(DFAState d, HashSet <int> nondeterministicAlts)
 {
     _altsWithProblem.addAll(nondeterministicAlts);   // track overall list
     _statesWithSyntacticallyAmbiguousAltsSet.Add(d);
     dfa.nfa.grammar.setOfNondeterministicDecisionNumbers.Add(
         dfa.DecisionNumber
         );
 }
Beispiel #8
0
 public virtual void ReportNondeterminism(DFAState d, HashSet <int> nondeterministicAlts)
 {
     _altsWithProblem.UnionWith(nondeterministicAlts);   // track overall list
     _statesWithSyntacticallyAmbiguousAltsSet.Add(d);
     _dfa.Nfa.Grammar.setOfNondeterministicDecisionNumbers.Add(
         _dfa.NfaStartStateDecisionNumber
         );
 }
 public GrammarInsufficientPredicatesMessage( DecisionProbe probe,
                                             DFAState problemState,
                                             IDictionary<int, ICollection<IToken>> altToLocations )
     : base(ErrorManager.MSG_INSUFFICIENT_PREDICATES)
 {
     this.probe = probe;
     this.problemState = problemState;
     this.altToLocations = altToLocations;
 }
Beispiel #10
0
        /** Each state in the DFA represents a different input sequence for an
         *  alt of the decision.  Given a DFA state, what is the semantic
         *  predicate context for a particular alt.
         */
        public virtual SemanticContext GetSemanticContextForAlt(DFAState d, int alt)
        {
            var altToPredMap = _stateToAltSetWithSemanticPredicatesMap.get(d);

            if (altToPredMap == null)
            {
                return(null);
            }
            return(altToPredMap.get(alt));
        }
Beispiel #11
0
        // S U P P O R T

        /** Given a start state and a target state, return true if start can reach
         *  target state.  Also, compute the set of DFA states
         *  that are on a path from start to target; return in states parameter.
         */
        protected virtual bool ReachesState(DFAState startState,
                                            DFAState targetState,
                                            HashSet <object> states)
        {
            if (startState == targetState)
            {
                states.Add(targetState);
                //[email protected]("found target DFA state "+targetState.getStateNumber());
                _stateReachable[startState.stateNumber] = REACHABLE_YES;
                return(true);
            }

            DFAState s = startState;

            // avoid infinite loops
            _stateReachable[s.stateNumber] = REACHABLE_BUSY;

            // look for a path to targetState among transitions for this state
            // stop when you find the first one; I'm pretty sure there is
            // at most one path to any DFA state with conflicting predictions
            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition t          = s.Transition(i);
                DFAState   edgeTarget = (DFAState)t.target;

                int targetStatus; //= stateReachable.get( edgeTarget.stateNumber );
                if (_stateReachable.TryGetValue(edgeTarget.stateNumber, out targetStatus))
                {
                    if (targetStatus == REACHABLE_BUSY)
                    { // avoid cycles; they say nothing
                        continue;
                    }
                    if (targetStatus == REACHABLE_YES)
                    { // return success!
                        _stateReachable[s.stateNumber] = REACHABLE_YES;
                        return(true);
                    }
                    if (targetStatus == REACHABLE_NO)
                    { // try another transition
                        continue;
                    }
                }

                // if null, target must be REACHABLE_UNKNOWN (i.e., unvisited)
                if (ReachesState(edgeTarget, targetState, states))
                {
                    states.Add(s);
                    _stateReachable[s.stateNumber] = REACHABLE_YES;
                    return(true);
                }
            }

            _stateReachable[s.stateNumber] = REACHABLE_NO;
            return(false); // no path to targetState found.
        }
Beispiel #12
0
        private HashSet <object> GetUnaliasedDFAStateSet(HashSet <object> dfaStatesWithRecursionProblems)
        {
            HashSet <object> dfaStatesUnaliased = new HashSet <object>();

            foreach (int stateI in dfaStatesWithRecursionProblems)
            {
                DFAState d = dfa.GetState(stateI);
                dfaStatesUnaliased.Add(d.stateNumber);
            }
            return(dfaStatesUnaliased);
        }
 public RecursionOverflowMessage( DecisionProbe probe,
                                 DFAState sampleBadState,
                                 int alt,
                                 ICollection<string> targetRules,
                                 ICollection<ICollection<NFAState>> callSiteStates )
     : base(ErrorManager.MSG_RECURSION_OVERLOW)
 {
     this.probe = probe;
     this.sampleBadState = sampleBadState;
     this.alt = alt;
     this.targetRules = targetRules;
     this.callSiteStates = callSiteStates;
 }
Beispiel #14
0
        protected virtual HashSet <object> GetDFAPathStatesToTarget(DFAState targetState)
        {
            HashSet <object> dfaStates = new HashSet <object>();

            _stateReachable = new Dictionary <int, int>();
            if (dfa == null || dfa.startState == null)
            {
                return(dfaStates);
            }
            bool reaches = ReachesState(dfa.startState, targetState, dfaStates);

            return(dfaStates);
        }
Beispiel #15
0
 public virtual void ReportNondeterminismResolvedWithSemanticPredicate(DFAState d)
 {
     // First, prevent a recursion warning on this state due to
     // pred resolution
     if (d.abortedDueToRecursionOverflow)
     {
         d.dfa.probe.RemoveRecursiveOverflowState(d);
     }
     _statesResolvedWithSemanticPredicatesSet.Add(d);
     //[email protected]("resolved with pred: "+d);
     dfa.nfa.grammar.setOfNondeterministicDecisionNumbersResolvedWithPredicates.Add(
         dfa.DecisionNumber
         );
 }
Beispiel #16
0
        /** Each state in the DFA represents a different input sequence for an
         *  alt of the decision.  Given a DFA state, what is the semantic
         *  predicate context for a particular alt.
         */
        public virtual SemanticContext GetSemanticContextForAlt(DFAState d, int alt)
        {
            IDictionary <int, SemanticContext> altToPredMap;

            _stateToAltSetWithSemanticPredicatesMap.TryGetValue(d, out altToPredMap);
            if (altToPredMap == null)
            {
                return(null);
            }

            SemanticContext result;

            altToPredMap.TryGetValue(alt, out result);
            return(result);
        }
Beispiel #17
0
        public virtual void ReportRecursionOverflow(DFAState d,
                                                    NFAConfiguration recursionNFAConfiguration)
        {
            // track the state number rather than the state as d will change
            // out from underneath us; hash wouldn't return any value

            // left-recursion is detected in start state.  Since we can't
            // call resolveNondeterminism() on the start state (it would
            // not look k=1 to get min single token lookahead), we must
            // prevent errors derived from this state.  Avoid start state
            if (d.stateNumber > 0)
            {
                int stateI = d.stateNumber;
                _stateToRecursionOverflowConfigurationsMap.Map(stateI, recursionNFAConfiguration);
            }
        }
Beispiel #18
0
        /** Walk DFA states, unlinking the nfa configs and whatever else I
         *  can to reduce memory footprint.
         */
        protected virtual void UnlinkUnneededStateData(DFAState d)
        {
            int sI = d.stateNumber;

            if (visited.Contains(sI))
            {
                return; // already visited
            }
            visited.Add(sI);
            d.nfaConfigurations = null;
            for (int i = 0; i < d.NumberOfTransitions; i++)
            {
                Transition edge       = (Transition)d.transition(i);
                DFAState   edgeTarget = ((DFAState)edge.target);
                UnlinkUnneededStateData(edgeTarget);
            }
        }
Beispiel #19
0
        /** Return a IList<Label> indicating an input sequence that can be matched
         *  from the start state of the DFA to the targetState (which is known
         *  to have a problem).
         */
        public virtual IList <Label> GetSampleNonDeterministicInputSequence(DFAState targetState)
        {
            HashSet <object> dfaStates = GetDFAPathStatesToTarget(targetState);

            _statesVisitedDuringSampleSequence = new HashSet <int>();
            IList <Label> labels = new List <Label>(); // may access ith element; use array

            if (dfa == null || dfa.startState == null)
            {
                return(labels);
            }
            GetSampleInputSequenceUsingStateSet(dfa.startState,
                                                targetState,
                                                dfaStates,
                                                labels);
            return(labels);
        }
Beispiel #20
0
        /** From list of lookahead sets (one per alt in decision), create
         *  an LL(1) DFA.  One edge per set.
         *
         *  s0-{alt1}->:o=>1
         *  | \
         *  |  -{alt2}->:o=>2
         *  |
         *  ...
         */
        public LL1DFA(int decisionNumber, NFAState decisionStartState, LookaheadSet[] altLook)
            : base(decisionNumber, decisionStartState)
        {
            DFAState s0 = NewState();

            StartState = s0;
            UnreachableAlts.Clear();
            for (int alt = 1; alt < altLook.Length; alt++)
            {
                DFAState acceptAltState = NewState();
                acceptAltState.IsAcceptState = true;
                SetAcceptState(alt, acceptAltState);
                acceptAltState.LookaheadDepth = 1;
                acceptAltState.CachedUniquelyPredicatedAlt = alt;
                Label e = GetLabelForSet(altLook[alt].TokenTypeSet);
                s0.AddTransition(acceptAltState, e);
            }
        }
Beispiel #21
0
 private void ComputeAltToProblemMaps(IEnumerable <int> dfaStatesUnaliased,
                                      IDictionary <int, IList <NFAConfiguration> > configurationsMap,
                                      IDictionary <int, IDictionary <string, ICollection <NFAState> > > altToTargetToCallSitesMap,
                                      IDictionary <int, DFAState> altToDFAState)
 {
     foreach (int stateI in dfaStatesUnaliased)
     {
         // walk this DFA's config list
         IList <NFAConfiguration> configs;
         configurationsMap.TryGetValue(stateI, out configs);
         for (int i = 0; i < configs.Count; i++)
         {
             NFAConfiguration      c = (NFAConfiguration)configs[i];
             NFAState              ruleInvocationState = _dfa.Nfa.GetState(c.State);
             Transition            transition0         = ruleInvocationState.transition[0];
             RuleClosureTransition @ref = (RuleClosureTransition)transition0;
             string targetRule          = ((NFAState)@ref.Target).enclosingRule.Name;
             int    altI = c.Alt;
             IDictionary <string, ICollection <NFAState> > targetToCallSiteMap;
             altToTargetToCallSitesMap.TryGetValue(altI, out targetToCallSiteMap);
             if (targetToCallSiteMap == null)
             {
                 targetToCallSiteMap             = new Dictionary <string, ICollection <NFAState> >();
                 altToTargetToCallSitesMap[altI] = targetToCallSiteMap;
             }
             ICollection <NFAState> callSites;
             targetToCallSiteMap.TryGetValue(targetRule, out callSites);
             if (callSites == null)
             {
                 callSites = new HashSet <NFAState>();
                 targetToCallSiteMap[targetRule] = callSites;
             }
             callSites.Add(ruleInvocationState);
             // track one problem DFA state per alt
             DFAState state;
             if (!altToDFAState.TryGetValue(altI, out state) || state == null)
             {
                 DFAState sampleBadState = _dfa.GetState(stateI);
                 altToDFAState[altI] = sampleBadState;
             }
         }
     }
 }
Beispiel #22
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);
            }
        }
Beispiel #23
0
        /** Return a list of edge labels from start state to targetState. */
        public List <IIntSet> GetEdgeLabels(DFAState targetState)
        {
            List <DFAState> dfaStates = GetAnyDFAPathToTarget(targetState);
            List <IIntSet>  labels    = new List <IIntSet>();

            for (int i = 0; i < dfaStates.Count - 1; i++)
            {
                DFAState d         = dfaStates[i];
                DFAState nextState = dfaStates[i + 1];
                // walk looking for edge whose target is next dfa state
                for (int j = 0; j < d.NumberOfTransitions; j++)
                {
                    Transition e = d.GetTransition(j);
                    if (e.Target.StateNumber == nextState.StateNumber)
                    {
                        labels.Add(e.Label.Set);
                    }
                }
            }
            return(labels);
        }
Beispiel #24
0
        // I N F O R M A T I O N  A B O U T  D E C I S I O N

        /** Return the sorted list of alts that conflict within a single state.
         *  Note that predicates may resolve the conflict.
         */
        public virtual IList <int> GetNonDeterministicAltsForState(DFAState targetState)
        {
            IEnumerable <int> nondetAlts = targetState.GetNonDeterministicAlts();

            if (nondetAlts == null)
            {
                return(null);
            }

            return(nondetAlts.OrderBy(i => i).ToList());

            //HashSet<int> nondetAlts = targetState.getNonDeterministicAlts();
            //if ( nondetAlts == null )
            //{
            //    return null;
            //}
            //List sorted = new LinkedList();
            //sorted.addAll( nondetAlts );
            //Collections.sort( sorted ); // make sure it's 1, 2, ...
            //return sorted;
        }
Beispiel #25
0
        /** From list of lookahead sets (one per alt in decision), create
         *  an LL(1) DFA.  One edge per set.
         *
         *  s0-{alt1}->:o=>1
         *  | \
         *  |  -{alt2}->:o=>2
         *  |
         *  ...
         */
        public LL1DFA(int decisionNumber, NFAState decisionStartState, LookaheadSet[] altLook)
        {
            DFAState s0 = NewState();

            startState                 = s0;
            nfa                        = decisionStartState.nfa;
            NumberOfAlts               = nfa.grammar.GetNumberOfAltsForDecisionNFA(decisionStartState);
            this.decisionNumber        = decisionNumber;
            this.NFADecisionStartState = decisionStartState;
            InitAltRelatedInfo();
            UnreachableAlts = null;
            for (int alt = 1; alt < altLook.Length; alt++)
            {
                DFAState acceptAltState = NewState();
                acceptAltState.acceptState = true;
                SetAcceptState(alt, acceptAltState);
                acceptAltState.LookaheadDepth = 1;
                acceptAltState.cachedUniquelyPredicatedAlt = alt;
                Label e = GetLabelForSet(altLook[alt].tokenTypeSet);
                s0.AddTransition(acceptAltState, e);
            }
        }
Beispiel #26
0
        protected virtual void IssueRecursionWarnings()
        {
            // RECURSION OVERFLOW
            ICollection <int> dfaStatesWithRecursionProblems =
                _stateToRecursionOverflowConfigurationsMap.Keys;
            // now walk truly unique (unaliased) list of dfa states with inf recur
            // Goal: create a map from alt to map<target,IList<callsites>>
            // Map<Map<String target, IList<NFAState call sites>>
            IDictionary <int, IDictionary <string, ICollection <NFAState> > > altToTargetToCallSitesMap =
                new Dictionary <int, IDictionary <string, ICollection <NFAState> > >();
            // track a single problem DFA state for each alt
            var altToDFAState = new Dictionary <int, DFAState>();

            ComputeAltToProblemMaps(dfaStatesWithRecursionProblems,
                                    _stateToRecursionOverflowConfigurationsMap,
                                    altToTargetToCallSitesMap, // output param
                                    altToDFAState);            // output param

            // walk each alt with recursion overflow problems and generate error
            ICollection <int> alts       = altToTargetToCallSitesMap.Keys;
            List <int>        sortedAlts = new List <int>(alts);

            sortedAlts.Sort();
            //Collections.sort( sortedAlts );
            foreach (int altI in sortedAlts)
            {
                var targetToCallSiteMap =
                    altToTargetToCallSitesMap.get(altI);
                var      targetRules    = targetToCallSiteMap.Keys;
                var      callSiteStates = targetToCallSiteMap.Values;
                DFAState sampleBadState = (DFAState)altToDFAState.get(altI);
                ErrorManager.RecursionOverflow(this,
                                               sampleBadState,
                                               altI,
                                               targetRules,
                                               callSiteStates);
            }
        }
Beispiel #27
0
        // S U P P O R T
        /** Given a start state and a target state, return true if start can reach
         *  target state.  Also, compute the set of DFA states
         *  that are on a path from start to target; return in states parameter.
         */
        protected virtual bool ReachesState( DFAState startState,
                                       DFAState targetState,
                                       HashSet<object> states )
        {
            if ( startState == targetState )
            {
                states.Add( targetState );
                //[email protected]("found target DFA state "+targetState.getStateNumber());
                _stateReachable[startState.StateNumber] = Reachable.Yes;
                return true;
            }

            DFAState s = startState;
            // avoid infinite loops
            _stateReachable[s.StateNumber] = Reachable.Busy;

            // look for a path to targetState among transitions for this state
            // stop when you find the first one; I'm pretty sure there is
            // at most one path to any DFA state with conflicting predictions
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition t = s.GetTransition( i );
                DFAState edgeTarget = (DFAState)t.Target;

                Reachable targetStatus; //= stateReachable.get( edgeTarget.stateNumber );
                if ( _stateReachable.TryGetValue( edgeTarget.StateNumber, out targetStatus ) )
                {
                    if ( targetStatus == Reachable.Busy )
                    { // avoid cycles; they say nothing
                        continue;
                    }
                    if ( targetStatus == Reachable.Yes )
                    { // return success!
                        _stateReachable[s.StateNumber] = Reachable.Yes;
                        return true;
                    }
                    if ( targetStatus == Reachable.No )
                    { // try another transition
                        continue;
                    }
                }

                // if null, target must be REACHABLE_UNKNOWN (i.e., unvisited)
                if ( ReachesState( edgeTarget, targetState, states ) )
                {
                    states.Add( s );
                    _stateReachable[s.StateNumber] = Reachable.Yes;
                    return true;
                }
            }

            _stateReachable[s.StateNumber] = Reachable.No;
            return false; // no path to targetState found.
        }
Beispiel #28
0
        /** From a set of edgeset->list-of-alts mappings, create a DFA
         *  that uses syn preds for all |list-of-alts|>1.
         */
        public LL1DFA(int decisionNumber,
                      NFAState decisionStartState,
                      MultiMap <IntervalSet, int> edgeMap)
        {
            DFAState s0 = NewState();

            startState                 = s0;
            nfa                        = decisionStartState.nfa;
            NumberOfAlts               = nfa.grammar.GetNumberOfAltsForDecisionNFA(decisionStartState);
            this.decisionNumber        = decisionNumber;
            this.NFADecisionStartState = decisionStartState;
            InitAltRelatedInfo();
            UnreachableAlts = null;
            foreach (var edgeVar in edgeMap)
            {
                IntervalSet edge = edgeVar.Key;
                IList <int> alts = edgeVar.Value;
                alts = alts.OrderBy(i => i).ToList();
                //Collections.sort( alts ); // make sure alts are attempted in order
                //[email protected](edge+" -> "+alts);
                DFAState s = NewState();
                s.LookaheadDepth = 1;
                Label e = GetLabelForSet(edge);
                s0.AddTransition(s, e);
                if (alts.Count == 1)
                {
                    s.acceptState = true;
                    int alt = alts[0];
                    SetAcceptState(alt, s);
                    s.cachedUniquelyPredicatedAlt = alt;
                }
                else
                {
                    // resolve with syntactic predicates.  Add edges from
                    // state s that test predicates.
                    s.IsResolvedWithPredicates = true;
                    for (int i = 0; i < alts.Count; i++)
                    {
                        int alt = (int)alts[i];
                        s.cachedUniquelyPredicatedAlt = NFA.INVALID_ALT_NUMBER;
                        DFAState predDFATarget = GetAcceptState(alt);
                        if (predDFATarget == null)
                        {
                            predDFATarget             = NewState(); // create if not there.
                            predDFATarget.acceptState = true;
                            predDFATarget.cachedUniquelyPredicatedAlt = alt;
                            SetAcceptState(alt, predDFATarget);
                        }
                        // add a transition to pred target from d

                        /*
                         * int walkAlt =
                         *  decisionStartState.translateDisplayAltToWalkAlt(alt);
                         * NFAState altLeftEdge = nfa.grammar.getNFAStateForAltOfDecision(decisionStartState, walkAlt);
                         * NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
                         * SemanticContext ctx = nfa.grammar.ll1Analyzer.getPredicates(altStartState);
                         * [email protected]("sem ctx = "+ctx);
                         * if ( ctx == null ) {
                         *  ctx = new SemanticContext.TruePredicate();
                         * }
                         * s.addTransition(predDFATarget, new Label(ctx));
                         */
                        SemanticContext.Predicate synpred =
                            GetSynPredForAlt(decisionStartState, alt);
                        if (synpred == null)
                        {
                            synpred = new SemanticContext.TruePredicate();
                        }
                        s.AddTransition(predDFATarget, new PredicateLabel(synpred));
                    }
                }
            }
            //[email protected]("dfa for preds=\n"+this);
        }
Beispiel #29
0
 public void RemoveState( DFAState d )
 {
     DFAState it;
     if ( _uniqueStates.TryGetValue( d, out it ) )
     {
         _uniqueStates.Remove( d );
         if ( it != null )
         {
             _numberOfStates--;
         }
     }
 }
Beispiel #30
0
        private int CalculateMaxLookaheadDepth(DFAState d, int depth)
        {
            // not cyclic; don't worry about termination
            // fail if pred edge.
            int max = depth;
            for (int i = 0; i < d.NumberOfTransitions; i++)
            {
                Transition t = d.GetTransition(i);
                //			if ( t.isSemanticPredicate() ) return Integer.MAX_VALUE;
                if (!t.IsSemanticPredicate)
                {
                    // if pure pred not gated, it must target stop state; don't count
                    DFAState edgeTarget = (DFAState)t.Target;
                    int m = CalculateMaxLookaheadDepth(edgeTarget, depth + 1);
                    max = Math.Max(max, m);
                }
            }

            return max;
        }
Beispiel #31
0
        protected virtual void CreateTransitionTableEntryForState( DFAState s )
        {
            /*
            [email protected]("createTransitionTableEntryForState s"+s.stateNumber+
                " dec "+s.dfa.decisionNumber+" cyclic="+s.dfa.isCyclic());
                */
            int smax = _max[s.StateNumber];
            int smin = _min[s.StateNumber];

            int[] stateTransitions = new int[smax - smin + 1];
            for ( int i = 0; i < stateTransitions.Length; i++ )
                stateTransitions[i] = EmptyValue;

            _transition[s.StateNumber] = stateTransitions;
            for ( int j = 0; j < s.NumberOfTransitions; j++ )
            {
                Transition edge = s.GetTransition( j );
                Label label = edge.Label;
                if ( label.IsAtom && label.Atom >= Label.MIN_CHAR_VALUE )
                {
                    int labelIndex = label.Atom - smin; // offset from 0
                    stateTransitions[labelIndex] = edge.Target.StateNumber;
                }
                else if ( label.IsSet )
                {
                    foreach ( var interval in ((IntervalSet)label.Set).Intervals )
                    {
                        for ( int i = Math.Max( interval.a, Label.MIN_CHAR_VALUE ); i <= interval.b; i++ )
                        {
                            stateTransitions[i - smin] = edge.Target.StateNumber;
                        }
                    }
                }
            }
            // track unique state transition tables so we can reuse
            int? edgeClass; // = edgeTransitionClassMap.get( stateTransitions );
            if ( _edgeTransitionClassMap.TryGetValue( stateTransitions, out edgeClass ) && edgeClass != null )
            {
                //[email protected]("we've seen this array before; size="+stateTransitions.size());
                _transitionEdgeTables[s.StateNumber] = edgeClass;
            }
            else
            {
                edgeClass = _edgeTransitionClass;
                _transitionEdgeTables[s.StateNumber] = edgeClass;
                _edgeTransitionClassMap[stateTransitions] = edgeClass;
                _edgeTransitionClass++;
            }
        }
Beispiel #32
0
        protected virtual void CreateMinMaxTables( DFAState s )
        {
            int smin = Label.MAX_CHAR_VALUE + 1;
            int smax = Label.MIN_ATOM_VALUE - 1;
            for ( int j = 0; j < s.NumberOfTransitions; j++ )
            {
                Transition edge = (Transition)s.GetTransition( j );
                Label label = edge.Label;
                if ( label.IsAtom )
                {
                    if ( label.Atom >= Label.MIN_CHAR_VALUE )
                    {
                        if ( label.Atom < smin )
                        {
                            smin = label.Atom;
                        }
                        if ( label.Atom > smax )
                        {
                            smax = label.Atom;
                        }
                    }
                }
                else if ( label.IsSet )
                {
                    IntervalSet labels = (IntervalSet)label.Set;
                    int lmin = labels.GetMinElement();
                    // if valid char (don't do EOF) and less than current min
                    if ( lmin < smin && lmin >= Label.MIN_CHAR_VALUE )
                    {
                        smin = labels.GetMinElement();
                    }
                    if ( labels.GetMaxElement() > smax )
                    {
                        smax = labels.GetMaxElement();
                    }
                }
            }

            if ( smax < 0 )
            {
                // must be predicates or pure EOT transition; just zero out min, max
                smin = Label.MIN_CHAR_VALUE;
                smax = Label.MIN_CHAR_VALUE;
            }

            _min[s.StateNumber] = (char)smin;
            _max[s.StateNumber] = (char)smax;

            if ( smax < 0 || smin > Label.MAX_CHAR_VALUE || smin < 0 )
            {
                ErrorManager.InternalError( "messed up: min=" + _min + ", max=" + _max );
            }
        }
Beispiel #33
0
 internal List<DFAState> GetAnyDFAPathToTarget(DFAState targetState)
 {
     HashSet<DFAState> visited = new HashSet<DFAState>();
     return GetAnyDFAPathToTarget(_dfa.StartState, targetState, visited);
 }
Beispiel #34
0
 internal virtual bool CalculateHasCycle(DFAState d, IDictionary<DFAState, Cyclic> busy)
 {
     busy[d] = Cyclic.Busy;
     for (int i = 0; i < d.NumberOfTransitions; i++)
     {
         Transition t = d.GetTransition(i);
         DFAState target = (DFAState)t.Target;
         Cyclic cond;
         if (!busy.TryGetValue(target, out cond))
             cond = Cyclic.Unknown;
         if (cond == Cyclic.Busy)
             return true;
         if (cond != Cyclic.Done && CalculateHasCycle(target, busy))
             return true;
     }
     busy[d] = Cyclic.Done;
     return false;
 }
Beispiel #35
0
 protected virtual void OptimizeEOTBranches( DFAState d )
 {
     int sI = d.stateNumber;
     if ( _visited.Contains( sI ) )
     {
         return; // already visited
     }
     _visited.Add( sI );
     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 only one edge coming out, it is EOT, and target is accept prune
         if ( PRUNE_TOKENS_RULE_SUPERFLUOUS_EOT_EDGES &&
             edgeTarget.IsAcceptState &&
             d.NumberOfTransitions == 1 &&
             edge.label.IsAtom &&
             edge.label.Atom == Label.EOT )
         {
             //[email protected]("state "+d+" can be pruned");
             // remove the superfluous EOT edge
             d.RemoveTransition( i );
             d.IsAcceptState = true; // make it an accept state
             // force it to uniquely predict the originally predicted state
             d.cachedUniquelyPredicatedAlt =
                 edgeTarget.GetUniquelyPredictedAlt();
             i--; // back up one so that i++ of loop iteration stays within bounds
         }
         OptimizeEOTBranches( edgeTarget );
     }
 }
Beispiel #36
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 );
     }
 }
Beispiel #37
0
 /** Walk DFA states, unlinking the nfa configs and whatever else I
  *  can to reduce memory footprint.
  */
 protected virtual void UnlinkUnneededStateData( DFAState d )
 {
     int sI = d.stateNumber;
     if ( visited.Contains( sI ) )
     {
         return; // already visited
     }
     visited.Add( sI );
     d.nfaConfigurations = null;
     for ( int i = 0; i < d.NumberOfTransitions; i++ )
     {
         Transition edge = (Transition)d.transition( i );
         DFAState edgeTarget = ( (DFAState)edge.target );
         UnlinkUnneededStateData( edgeTarget );
     }
 }
Beispiel #38
0
 /** Return a list of alts whose predicate context was insufficient to
  *  resolve a nondeterminism for state d.
  */
 public virtual IDictionary <int, ICollection <IToken> > GetIncompletelyCoveredAlts(DFAState d)
 {
     return(_stateToIncompletelyCoveredAltsMap.get(d));
 }
Beispiel #39
0
        internal List <DFAState> GetAnyDFAPathToTarget(DFAState targetState)
        {
            HashSet <DFAState> visited = new HashSet <DFAState>();

            return(GetAnyDFAPathToTarget(_dfa.StartState, targetState, visited));
        }
Beispiel #40
0
        internal virtual bool CalculateHasSynPred(DFAState d, HashSet<DFAState> busy)
        {
            busy.Add(d);
            for (int i = 0; i < d.NumberOfTransitions; i++)
            {
                Transition t = d.GetTransition(i);
                if (t.IsSemanticPredicate)
                {
                    SemanticContext ctx = t.Label.SemanticContext;
                    //				if ( ctx.toString().indexOf("synpred")>=0 ) {
                    //					System.out.println("has pred "+ctx.toString()+" "+ctx.isSyntacticPredicate());
                    //					System.out.println(((SemanticContext.Predicate)ctx).predicateAST.token);
                    //				}
                    if (ctx.IsSyntacticPredicate)
                        return true;
                }
                DFAState edgeTarget = (DFAState)t.Target;
                if (!busy.Contains(edgeTarget) &&CalculateHasSynPred(edgeTarget, busy))
                    return true;
            }

            return false;
        }
Beispiel #41
0
        /** A special state is huge (too big for state tables) or has a predicated
         *  edge.  Generate a simple if-then-else.  Cannot be an accept state as
         *  they have no emanating edges.  Don't worry about switch vs if-then-else
         *  because if you get here, the state is super complicated and needs an
         *  if-then-else.  This is used by the new DFA scheme created June 2006.
         */
        public virtual StringTemplate GenerateSpecialState( DFAState s )
        {
            StringTemplate stateST;
            stateST = templates.GetInstanceOf( "cyclicDFAState" );
            stateST.SetAttribute( "needErrorClause", true );
            stateST.SetAttribute( "semPredState", s.IsResolvedWithPredicates );
            stateST.SetAttribute( "stateNumber", s.stateNumber );
            stateST.SetAttribute( "decisionNumber", s.dfa.decisionNumber );

            bool foundGatedPred = false;
            StringTemplate eotST = null;
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition edge = (Transition)s.Transition( i );
                StringTemplate edgeST;
                if ( edge.label.Atom == Label.EOT )
                {
                    // this is the default clause; has to held until last
                    edgeST = templates.GetInstanceOf( "eotDFAEdge" );
                    stateST.RemoveAttribute( "needErrorClause" );
                    eotST = edgeST;
                }
                else
                {
                    edgeST = templates.GetInstanceOf( "cyclicDFAEdge" );
                    StringTemplate exprST =
                        GenLabelExpr( templates, edge, 1 );
                    edgeST.SetAttribute( "labelExpr", exprST );
                }
                edgeST.SetAttribute( "edgeNumber", i + 1 );
                edgeST.SetAttribute( "targetStateNumber",
                                     edge.target.stateNumber );
                // stick in any gated predicates for any edge if not already a pred
                if ( !edge.label.IsSemanticPredicate )
                {
                    DFAState t = (DFAState)edge.target;
                    SemanticContext preds = t.GetGatedPredicatesInNFAConfigurations();
                    if ( preds != null )
                    {
                        foundGatedPred = true;
                        StringTemplate predST = preds.GenExpr( this,
                                                              Templates,
                                                              t.dfa );
                        edgeST.SetAttribute( "predicates", predST.ToString() );
                    }
                }
                if ( edge.label.Atom != Label.EOT )
                {
                    stateST.SetAttribute( "edges", edgeST );
                }
            }
            if ( foundGatedPred )
            {
                // state has >= 1 edge with a gated pred (syn or sem)
                // must rewind input first, set flag.
                stateST.SetAttribute( "semPredState", foundGatedPred );
            }
            if ( eotST != null )
            {
                stateST.SetAttribute( "edges", eotST );
            }
            return stateST;
        }
Beispiel #42
0
 /** Return a list of edge labels from start state to targetState. */
 public List<IIntSet> GetEdgeLabels(DFAState targetState)
 {
     List<DFAState> dfaStates = GetAnyDFAPathToTarget(targetState);
     List<IIntSet> labels = new List<IIntSet>();
     for (int i = 0; i < dfaStates.Count - 1; i++)
     {
         DFAState d = dfaStates[i];
         DFAState nextState = dfaStates[i + 1];
         // walk looking for edge whose target is next dfa state
         for (int j = 0; j < d.NumberOfTransitions; j++)
         {
             Transition e = d.GetTransition(j);
             if (e.Target.StateNumber == nextState.StateNumber)
             {
                 labels.Add(e.Label.Set);
             }
         }
     }
     return labels;
 }
Beispiel #43
0
        internal virtual bool CalculateHasSemPred(DFAState d, HashSet<DFAState> busy)
        {
            busy.Add(d);
            for (int i = 0; i < d.NumberOfTransitions; i++)
            {
                Transition t = d.GetTransition(i);
                if (t.IsSemanticPredicate)
                {
                    SemanticContext ctx = t.Label.SemanticContext;
                    if (ctx.HasUserSemanticPredicate)
                        return true;
                }
                DFAState edgeTarget = (DFAState)t.Target;
                if (!busy.Contains(edgeTarget) && CalculateHasSemPred(edgeTarget, busy))
                    return true;
            }

            return false;
        }
Beispiel #44
0
 /** Currently the analysis reports issues between token definitions, but
  *  we don't print out warnings in favor of just picking the first token
  *  definition found in the grammar ala lex/flex.
  */
 public virtual void ReportLexerRuleNondeterminism(DFAState d, HashSet <int> nondeterministicAlts)
 {
     stateToSyntacticallyAmbiguousTokensRuleAltsMap[d] = nondeterministicAlts;
 }
Beispiel #45
0
        /** Set up the EOT and EOF tables; we cannot put -1 min/max values so
         *  we need another way to test that in the DFA transition function.
         */
        protected virtual void CreateEOTAndEOFTables( DFAState s )
        {
            for ( int j = 0; j < s.NumberOfTransitions; j++ )
            {
                Transition edge = s.GetTransition( j );
                Label label = edge.Label;
                if ( label.IsAtom )
                {
                    if ( label.Atom == Label.EOT )
                    {
                        // eot[s] points to accept state
                        _eot[s.StateNumber] = edge.Target.StateNumber;
                    }
                    else if ( label.Atom == Label.EOF )
                    {
                        // eof[s] points to accept state
                        _eof[s.StateNumber] = edge.Target.StateNumber;
                    }
                }
                else if ( label.IsSet )
                {
                    if ( label.Set.Contains( Label.EOT ) )
                    {
                        _eot[s.StateNumber] = edge.Target.StateNumber;
                    }

                    if ( label.Set.Contains( Label.EOF ) )
                    {
                        _eof[s.StateNumber] = edge.Target.StateNumber;
                    }
                }
            }
        }
Beispiel #46
0
 /** You can generate a switch rather than if-then-else for a DFA state
  *  if there are no semantic predicates and the number of edge label
  *  values is small enough; e.g., don't generate a switch for a state
  *  containing an edge label such as 20..52330 (the resulting byte codes
  *  would overflow the method 65k limit probably).
  */
 protected internal virtual bool CanGenerateSwitch( DFAState s )
 {
     if ( !GenerateSwitchesWhenPossible )
     {
         return false;
     }
     int size = 0;
     for ( int i = 0; i < s.NumberOfTransitions; i++ )
     {
         Transition edge = (Transition)s.Transition( i );
         if ( edge.label.IsSemanticPredicate )
         {
             return false;
         }
         // can't do a switch if the edges are going to require predicates
         if ( edge.label.Atom == Label.EOT )
         {
             int EOTPredicts = ( (DFAState)edge.target ).GetUniquelyPredictedAlt();
             if ( EOTPredicts == NFA.INVALID_ALT_NUMBER )
             {
                 // EOT target has to be a predicate then; no unique alt
                 return false;
             }
         }
         // if target is a state with gated preds, we need to use preds on
         // this edge then to reach it.
         if ( ( (DFAState)edge.target ).GetGatedPredicatesInNFAConfigurations() != null )
         {
             return false;
         }
         size += edge.label.Set.Count;
     }
     if ( s.NumberOfTransitions < MinSwitchAlts ||
          size > MaxSwitchCaseLabels )
     {
         return false;
     }
     return true;
 }
Beispiel #47
0
        protected virtual void CreateSpecialTable( DFAState s )
        {
            // number all special states from 0...n-1 instead of their usual numbers
            bool hasSemPred = false;

            // TODO this code is very similar to canGenerateSwitch.  Refactor to share
            for ( int j = 0; j < s.NumberOfTransitions; j++ )
            {
                Transition edge = (Transition)s.GetTransition( j );
                Label label = edge.Label;
                // can't do a switch if the edges have preds or are going to
                // require gated predicates
                if ( label.IsSemanticPredicate ||
                     ( (DFAState)edge.Target ).GetGatedPredicatesInNFAConfigurations() != null )
                {
                    hasSemPred = true;
                    break;
                }
            }
            // if has pred or too big for table, make it special
            int smax = _max[s.StateNumber];
            int smin = _min[s.StateNumber];
            if ( hasSemPred || smax - smin > MAX_STATE_TRANSITIONS_FOR_TABLE )
            {
                _special[s.StateNumber] = _uniqueCompressedSpecialStateNum;
                _uniqueCompressedSpecialStateNum++;
                _specialStates.Add( s );
            }
            else
            {
                _special[s.StateNumber] = EmptyValue; // not special
            }
        }
Beispiel #48
0
 public virtual void ReportIncompletelyCoveredAlts(DFAState d,
                                                   IDictionary <int, ICollection <IToken> > altToLocationsReachableWithoutPredicate)
 {
     _stateToIncompletelyCoveredAltsMap[d] = altToLocationsReachableWithoutPredicate;
 }
Beispiel #49
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;
        }
Beispiel #51
0
 public virtual DFAState NewState()
 {
     DFAState n = new DFAState( this );
     n.StateNumber = _stateCounter;
     _stateCounter++;
     _states.Resize( n.StateNumber + 1 );
     _states[n.StateNumber] = n; // track state num to state
     return n;
 }
Beispiel #52
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.GetTransition(i);
                if (StripNonreducedStates)
                {
                    DFAState target = edge.Target as DFAState;
                    // don't generate nodes for terminal states
                    if (target != null && target.AcceptStateReachable != 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);
            }
        }
Beispiel #53
0
 /** Add a transition from this state to target with label.  Return
  *  the transition number from 0..n-1.
  */
 public virtual int AddTransition(DFAState target, Label label)
 {
     _transitions.Add(new Transition(label, target));
     return(_transitions.Count - 1);
 }
Beispiel #54
0
 public virtual void SetAcceptState( int alt, DFAState acceptState )
 {
     _altToAcceptState[alt] = acceptState;
 }
Beispiel #55
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'
            }
        }
Beispiel #56
0
 public virtual void SetState( int stateNumber, DFAState d )
 {
     _states[stateNumber] = d;
 }
Beispiel #57
0
        protected virtual HashSet<object> GetDFAPathStatesToTarget( DFAState targetState )
        {
            HashSet<object> dfaStates = new HashSet<object>();
            _stateReachable = new Dictionary<int, Reachable>();
            if ( _dfa == null || _dfa.StartState == null )
            {
                return dfaStates;
            }

            bool reaches = ReachesState( _dfa.StartState, targetState, dfaStates );
            return dfaStates;
        }
Beispiel #58
0
        /** Add a new DFA state to this DFA if not already present.
         *  To force an acyclic, fixed maximum depth DFA, just always
         *  return the incoming state.  By not reusing old states,
         *  no cycles can be created.  If we're doing fixed k lookahead
         *  don't updated uniqueStates, just return incoming state, which
         *  indicates it's a new state.
         */
        protected internal virtual DFAState AddState( DFAState d )
        {
            if ( UserMaxLookahead > 0 )
            {
                return d;
            }
            // does a DFA state exist already with everything the same
            // except its state number?
            DFAState existing;
            _uniqueStates.TryGetValue(d, out existing);
            if ( existing != null )
            {
                /*
                [email protected]("state "+d.stateNumber+" exists as state "+
                    existing.stateNumber);
                    */
                // already there...get the existing DFA state
                return existing;
            }

            // if not there, then add new state.
            _uniqueStates[d] = d;
            _numberOfStates++;
            return d;
        }
Beispiel #59
0
        // T R A C K I N G  M E T H O D S

        /** Report the fact that DFA state d is not a state resolved with
         *  predicates and yet it has no emanating edges.  Usually this
         *  is a result of the closure/reach operations being unable to proceed
         */
        public virtual void ReportDanglingState(DFAState d)
        {
            _danglingStates.Add(d);
        }
Beispiel #60
0
 /** Add a transition from this state to target with label.  Return
  *  the transition number from 0..n-1.
  */
 public virtual int AddTransition( DFAState target, Label label )
 {
     _transitions.Add( new Transition( label, target ) );
     return _transitions.Count - 1;
 }