public IntervalSet GetFollowSet() { int symbol = UnknownSymbol; int symbolPosition = _input.Index + _lookAheadPosition - 1; if (_lookAheadPosition == 0 && _lookBehindPosition == 0 && _contexts.Count == 0) { IntervalSet allTokens = new IntervalSet(); foreach (var transition in Network.Transitions.Where(i => i.IsMatch)) { allTokens.UnionWith(transition.MatchSet); } return(allTokens); } Stopwatch updateTimer = Stopwatch.StartNew(); List <InterpretTrace> existing = new List <InterpretTrace>(_contexts); SortedSet <int> states = new SortedSet <int>(); HashSet <InterpretTrace> contexts = new HashSet <InterpretTrace>(EqualityComparer <InterpretTrace> .Default); foreach (var context in existing) { states.Add(context.EndContext.State.Id); StepForward(contexts, states, context, symbol, symbolPosition, PreventContextType.None); states.Clear(); } IntervalSet result = new IntervalSet(); if (contexts.Count > 0) { foreach (var context in contexts) { var lastMatch = context.Transitions.Last.Value; if (lastMatch.Transition.IsMatch) { result.UnionWith(lastMatch.Transition.MatchSet); } } } long nfaUpdateTime = updateTimer.ElapsedMilliseconds; return(result); }
public IntervalSet GetFollowSet() { int symbol = UnknownSymbol; int symbolPosition = _input.Index + _lookAheadPosition - 1; if (_lookAheadPosition == 0 && _lookBehindPosition == 0 && _contexts.Count == 0) { IntervalSet allTokens = new IntervalSet(); foreach (var transition in Network.Transitions.Where(i => i.IsMatch)) allTokens.UnionWith(transition.MatchSet); return allTokens; } Stopwatch updateTimer = Stopwatch.StartNew(); List<InterpretTrace> existing = new List<InterpretTrace>(_contexts); SortedSet<int> states = new SortedSet<int>(); HashSet<InterpretTrace> contexts = new HashSet<InterpretTrace>(EqualityComparer<InterpretTrace>.Default); foreach (var context in existing) { states.Add(context.EndContext.State.Id); StepForward(contexts, states, context, symbol, symbolPosition, PreventContextType.None); states.Clear(); } IntervalSet result = new IntervalSet(); if (contexts.Count > 0) { foreach (var context in contexts) { var lastMatch = context.Transitions.Last.Value; if (lastMatch.Transition.IsMatch) result.UnionWith(lastMatch.Transition.MatchSet); } } long nfaUpdateTime = updateTimer.ElapsedMilliseconds; return result; }
public IntervalSet GetFollowSet(PreventContextType preventContextType) { if (_followSet != null && _followSet[(int)preventContextType] != null) { return(_followSet[(int)preventContextType]); } IntervalSet[] sets = _followSet ?? new IntervalSet[Enum.GetValues(typeof(PreventContextType)).Cast <int>().Max() + 1]; IntervalSet set = new IntervalSet(); var queue = new Queue <Tuple <Transition, PreventContextType> >(OutgoingTransitions.Select(i => Tuple.Create(i, preventContextType))); var comparer = new TupleEqualityComparer <Transition, PreventContextType>(ObjectReferenceEqualityComparer <Transition> .Default, null); var visited = new HashSet <Tuple <Transition, PreventContextType> >(queue, comparer); while (queue.Count > 0) { var pair = queue.Dequeue(); Transition transition = pair.Item1; PreventContextType nextPreventContextType = pair.Item2; if (transition.IsContext) { switch (nextPreventContextType) { case PreventContextType.Pop: if (!transition.IsRecursive && transition is PopContextTransition) { continue; } break; case PreventContextType.PopRecursive: if (transition.IsRecursive && (transition is PopContextTransition)) { continue; } break; case PreventContextType.Push: if (!transition.IsRecursive && transition is PushContextTransition) { continue; } break; case PreventContextType.PushRecursive: if (transition.IsRecursive && (transition is PushContextTransition)) { continue; } break; default: break; } } if (transition.IsEpsilon || transition.IsContext) { // the preventContextType can only change if we're following a another context transition if (transition.IsContext) { nextPreventContextType = PreventContextType.None; if (transition.SourceState.IsOptimized) { if (transition is PushContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } } if (transition.TargetState._followSet != null && transition.TargetState._followSet[(int)nextPreventContextType] != null) { set.UnionWith(transition.TargetState._followSet[(int)nextPreventContextType]); } else { foreach (var outgoing in transition.TargetState.OutgoingTransitions) { var nextPair = Tuple.Create(outgoing, nextPreventContextType); if (visited.Add(nextPair)) { queue.Enqueue(Tuple.Create(outgoing, nextPreventContextType)); } } } } else { set.UnionWith(transition.MatchSet); } } _followSet = sets; _followSet[(int)preventContextType] = set; return(set); }