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; }
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); }