public bool TryStepBackward()
        {
            if (_failedBackward || _beginningOfFile)
                return false;

            if (_input.Index - _lookBehindPosition <= 0)
            {
                _beginningOfFile = true;
                return false;
            }

            IToken token = _input.LT(-1 - _lookBehindPosition);
            if (token == null)
            {
                _beginningOfFile = true;
                return false;
            }

            int symbol = token.Type;
            int symbolPosition = token.TokenIndex;

            /*
             * Update the non-deterministic trace
             */

            Stopwatch updateTimer = Stopwatch.StartNew();

            if (_lookAheadPosition == 0 && _lookBehindPosition == 0 && _contexts.Count == 0)
            {
                HashSet<InterpretTrace> initialContexts = new HashSet<InterpretTrace>(EqualityComparer<InterpretTrace>.Default);

                /* create our initial set of states as the ones at the target end of a match transition
                 * that contains 'symbol' in the match set.
                 */
                List<Transition> transitions = new List<Transition>(_network.Transitions.Where(i => i.MatchesSymbol(symbol)));
                foreach (var transition in transitions)
                {
                    if (ExcludedStartRules.Contains(Network.StateRules[transition.SourceState.Id]))
                        continue;

                    if (ExcludedStartRules.Contains(Network.StateRules[transition.TargetState.Id]))
                        continue;

                    ContextFrame startContext = new ContextFrame(transition.TargetState, null, null, this);
                    ContextFrame endContext = new ContextFrame(transition.TargetState, null, null, this);
                    initialContexts.Add(new InterpretTrace(startContext, endContext));
                }

                _contexts.AddRange(initialContexts);

#if DFA
                DeterministicState deterministicState = new DeterministicState(_contexts.Select(i => i.StartContext));
                _deterministicTrace = new DeterministicTrace(deterministicState, deterministicState);
#endif
            }

            List<InterpretTrace> existing = new List<InterpretTrace>(_contexts);
            _contexts.Clear();
            SortedSet<int> states = new SortedSet<int>();
            HashSet<InterpretTrace> contexts = new HashSet<InterpretTrace>(EqualityComparer<InterpretTrace>.Default);
#if false
            HashSet<ContextFrame> existingUnique = new HashSet<ContextFrame>(existing.Select(i => i.StartContext), EqualityComparer<ContextFrame>.Default);
            Contract.Assert(existingUnique.Count == existing.Count);
#endif

            foreach (var context in existing)
            {
                states.Add(context.StartContext.State.Id);
                StepBackward(contexts, states, context, symbol, symbolPosition, PreventContextType.None);
                states.Clear();
            }

            bool success = false;
            if (contexts.Count > 0)
            {
                _contexts.AddRange(contexts);
                if (TrackBoundedContexts)
                    _boundedStartContexts.UnionWith(_contexts.Where(i => i.BoundedStart));
                success = true;
            }
            else
            {
                _contexts.AddRange(existing);
            }

            long nfaUpdateTime = updateTimer.ElapsedMilliseconds;

#if DFA
            /*
             * Update the deterministic trace
             */

            updateTimer.Restart();

            DeterministicTransition deterministicTransition = _deterministicTrace.StartState.IncomingTransitions.SingleOrDefault(i => i.MatchSet.Contains(symbol));
            if (deterministicTransition == null)
            {
                DeterministicState sourceState = new DeterministicState(contexts.Select(i => i.StartContext));
                DeterministicState targetState = _deterministicTrace.StartState;
                deterministicTransition = targetState.IncomingTransitions.SingleOrDefault(i => i.SourceState.Equals(sourceState));
                if (deterministicTransition == null)
                {
                    deterministicTransition = new DeterministicTransition(targetState);
                    sourceState.AddTransition(deterministicTransition);
                }

                deterministicTransition.MatchSet.Add(symbol);
            }

            IEnumerable<DeterministicTraceTransition> deterministicTransitions = Enumerable.Repeat(new DeterministicTraceTransition(deterministicTransition, symbol, symbolPosition, this), 1);
            deterministicTransitions = deterministicTransitions.Concat(_deterministicTrace.Transitions);
            _deterministicTrace = new DeterministicTrace(deterministicTransition.SourceState, _deterministicTrace.EndState, deterministicTransitions);

            long dfaUpdateTime = updateTimer.ElapsedMilliseconds;
#endif

            if (success)
                _lookBehindPosition++;

            if (!success)
                _failedBackward = true;

            return success;
        }
Exemplo n.º 2
0
        public bool TryStepBackward()
        {
            if (_failedBackward || _beginningOfFile)
            {
                return(false);
            }

            if (_input.Index - _lookBehindPosition <= 0)
            {
                _beginningOfFile = true;
                return(false);
            }

            IToken token = _input.LT(-1 - _lookBehindPosition);

            if (token == null)
            {
                _beginningOfFile = true;
                return(false);
            }

            int symbol         = token.Type;
            int symbolPosition = token.TokenIndex;

            /*
             * Update the non-deterministic trace
             */

            Stopwatch updateTimer = Stopwatch.StartNew();

            if (_lookAheadPosition == 0 && _lookBehindPosition == 0 && _contexts.Count == 0)
            {
                HashSet <InterpretTrace> initialContexts = new HashSet <InterpretTrace>(EqualityComparer <InterpretTrace> .Default);

                /* create our initial set of states as the ones at the target end of a match transition
                 * that contains 'symbol' in the match set.
                 */
                List <Transition> transitions = new List <Transition>(_network.Transitions.Where(i => i.MatchesSymbol(symbol)));
                foreach (var transition in transitions)
                {
                    if (ExcludedStartRules.Contains(Network.StateRules[transition.SourceState.Id]))
                    {
                        continue;
                    }

                    if (ExcludedStartRules.Contains(Network.StateRules[transition.TargetState.Id]))
                    {
                        continue;
                    }

                    ContextFrame startContext = new ContextFrame(transition.TargetState, null, null, this);
                    ContextFrame endContext   = new ContextFrame(transition.TargetState, null, null, this);
                    initialContexts.Add(new InterpretTrace(startContext, endContext));
                }

                _contexts.AddRange(initialContexts);

#if DFA
                DeterministicState deterministicState = new DeterministicState(_contexts.Select(i => i.StartContext));
                _deterministicTrace = new DeterministicTrace(deterministicState, deterministicState);
#endif
            }

            List <InterpretTrace> existing = new List <InterpretTrace>(_contexts);
            _contexts.Clear();
            SortedSet <int>          states   = new SortedSet <int>();
            HashSet <InterpretTrace> contexts = new HashSet <InterpretTrace>(EqualityComparer <InterpretTrace> .Default);
#if false
            HashSet <ContextFrame> existingUnique = new HashSet <ContextFrame>(existing.Select(i => i.StartContext), EqualityComparer <ContextFrame> .Default);
            Contract.Assert(existingUnique.Count == existing.Count);
#endif

            foreach (var context in existing)
            {
                states.Add(context.StartContext.State.Id);
                StepBackward(contexts, states, context, symbol, symbolPosition, PreventContextType.None);
                states.Clear();
            }

            bool success = false;
            if (contexts.Count > 0)
            {
                _contexts.AddRange(contexts);
                if (TrackBoundedContexts)
                {
                    _boundedStartContexts.UnionWith(_contexts.Where(i => i.BoundedStart));
                }
                success = true;
            }
            else
            {
                _contexts.AddRange(existing);
            }

            long nfaUpdateTime = updateTimer.ElapsedMilliseconds;

#if DFA
            /*
             * Update the deterministic trace
             */

            updateTimer.Restart();

            DeterministicTransition deterministicTransition = _deterministicTrace.StartState.IncomingTransitions.SingleOrDefault(i => i.MatchSet.Contains(symbol));
            if (deterministicTransition == null)
            {
                DeterministicState sourceState = new DeterministicState(contexts.Select(i => i.StartContext));
                DeterministicState targetState = _deterministicTrace.StartState;
                deterministicTransition = targetState.IncomingTransitions.SingleOrDefault(i => i.SourceState.Equals(sourceState));
                if (deterministicTransition == null)
                {
                    deterministicTransition = new DeterministicTransition(targetState);
                    sourceState.AddTransition(deterministicTransition);
                }

                deterministicTransition.MatchSet.Add(symbol);
            }

            IEnumerable <DeterministicTraceTransition> deterministicTransitions = Enumerable.Repeat(new DeterministicTraceTransition(deterministicTransition, symbol, symbolPosition, this), 1);
            deterministicTransitions = deterministicTransitions.Concat(_deterministicTrace.Transitions);
            _deterministicTrace      = new DeterministicTrace(deterministicTransition.SourceState, _deterministicTrace.EndState, deterministicTransitions);

            long dfaUpdateTime = updateTimer.ElapsedMilliseconds;
#endif

            if (success)
            {
                _lookBehindPosition++;
            }

            if (!success)
            {
                _failedBackward = true;
            }

            return(success);
        }