private InterpretTrace(ContextFrame startContext, ContextFrame endContext, LinkedList <InterpretTraceTransition> transitions, bool boundedStart, bool boundedEnd, bool copyTransitionsByReference) { StartContext = startContext; EndContext = endContext; if (copyTransitionsByReference) { Transitions = transitions; } else { Transitions = new LinkedList <InterpretTraceTransition>(transitions); } BoundedStart = boundedStart; BoundedEnd = boundedEnd; }
public bool TryStepBackward([NotNull] Transition transition, int symbol, int symbolPosition, out InterpretTrace result) { Requires.NotNull(transition, nameof(transition)); Debug.Assert(Network.States.ContainsKey(transition.SourceState.Id), "Attempted to step outside the network."); Debug.Assert(Network.States.ContainsKey(transition.TargetState.Id), "Attempted to step into the network."); bool boundedStart = BoundedStart; if (!boundedStart && Transitions.Count > 0) { bool ruleBoundary = false; PushContextTransition pushContextTransition = Transitions.First.Value.Transition as PushContextTransition; if (pushContextTransition != null) { /* the rule boundary transfers from outside the rule to inside the rule (or * inside a rule invoked by this rule) */ // first, check if the transition goes to this rule ruleBoundary = Interpreter.BoundaryRules.Contains(Network.StateRules[pushContextTransition.TargetState.Id]); // next, check if the transition starts outside this rule and goes through this rule if (!ruleBoundary) { ruleBoundary = pushContextTransition.ContextIdentifiers .Skip(1) .Any(i => Interpreter.BoundaryRules.Contains(Network.ContextRules[i])); } } if (ruleBoundary) { bool nested = false; for (ContextFrame parent = StartContext.Parent; parent != null; parent = parent.Parent) { Debug.Assert(parent.Context != null); RuleBinding contextRule = Network.ContextRules[parent.Context.Value]; if (Interpreter.BoundaryRules.Contains(contextRule)) { nested = true; } } boundedStart = !nested; } } result = null; if (transition.IsMatch) { if (symbol != NetworkInterpreter.UnknownSymbol && !transition.MatchesSymbol(symbol)) { return(false); } ContextFrame startContext = new ContextFrame(transition.SourceState, this.StartContext.Context, this.StartContext.Parent, Interpreter); result = new InterpretTrace(startContext, this.EndContext, this.Transitions, boundedStart, this.BoundedEnd, boundedStart); if (!boundedStart) { if (!Interpreter.TrackContextTransitions && result.Transitions.Count > 0 && result.Transitions.First.Value.Symbol == null) { result.Transitions.RemoveFirst(); } result.Transitions.AddFirst(new InterpretTraceTransition(transition, symbol, symbolPosition, Interpreter)); } return(true); } PreventContextType preventContextType = PreventContextType.None; if (transition.SourceState.IsOptimized && transition.IsContext) { if (transition is PushContextTransition) { preventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { preventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } if (symbol != NetworkInterpreter.UnknownSymbol && !transition.SourceState.GetSourceSet(preventContextType).Contains(symbol)) { return(false); } if (transition.IsContext) { PopContextTransition popContextTransition = transition as PopContextTransition; if (popContextTransition != null) { ContextFrame subContext = this.StartContext; foreach (var label in popContextTransition.ContextIdentifiers.Reverse()) { subContext = new ContextFrame(popContextTransition.SourceState, null, new ContextFrame(subContext.State, label, subContext.Parent, Interpreter), Interpreter); } result = new InterpretTrace(subContext, this.EndContext, this.Transitions, boundedStart, this.BoundedEnd, boundedStart); if (!boundedStart) { if (!Interpreter.TrackContextTransitions && result.Transitions.Count > 0 && result.Transitions.First.Value.Symbol == null) { result.Transitions.RemoveFirst(); } result.Transitions.AddFirst(new InterpretTraceTransition(transition, Interpreter)); } return(true); } PushContextTransition pushContextTransition = transition as PushContextTransition; if (pushContextTransition != null) { ContextFrame startContext = this.StartContext; ContextFrame endContext = this.EndContext; for (int i = pushContextTransition.ContextIdentifiers.Count - 1; i >= 0; i--) { int label = pushContextTransition.ContextIdentifiers[i]; if (startContext.Parent != null) { Debug.Assert(startContext.Parent.Context.HasValue); // if the start context has a state stack, pop an item off it if (startContext.Parent.Context != label) { return(false); } startContext = new ContextFrame(transition.SourceState, null, startContext.Parent.Parent, Interpreter); } else { int?headContext = endContext.HeadContext; if (headContext != null) { if (!Network.Optimizer.CanNestContexts(label, headContext.Value)) { return(false); } } else { if (!Network.Optimizer.IsStateInContext(label, endContext.State.Id)) { return(false); } } ContextFrame headContextFrame = null; for (int j = 0; j <= i; j++) { headContextFrame = new ContextFrame(null, pushContextTransition.ContextIdentifiers[j], headContextFrame, Interpreter); } // else we add a "predicate" to the end context endContext = endContext.AddHeadContext(headContextFrame); if (!object.ReferenceEquals(startContext.State, transition.SourceState)) { startContext = new ContextFrame(transition.SourceState, startContext.Context, startContext.Parent, Interpreter); } break; } } result = new InterpretTrace(startContext, endContext, this.Transitions, boundedStart, this.BoundedEnd, boundedStart); if (!boundedStart) { if (!Interpreter.TrackContextTransitions && result.Transitions.Count > 0 && result.Transitions.First.Value.Symbol == null) { result.Transitions.RemoveFirst(); } result.Transitions.AddFirst(new InterpretTraceTransition(transition, Interpreter)); } return(true); } throw new NotSupportedException("Unknown context transition."); } else if (transition.IsEpsilon) { ContextFrame startContext = new ContextFrame(transition.SourceState, this.StartContext.Context, this.StartContext.Parent, Interpreter); result = new InterpretTrace(startContext, this.EndContext, this.Transitions, boundedStart, this.BoundedEnd, true); return(true); } throw new NotSupportedException("Unknown transition type."); }
public InterpretTrace(ContextFrame startContext, ContextFrame endContext) : this(startContext, endContext, EmptyTransitions, false, false, false) { }
public bool TryStepForward() { if (_failedForward || _endOfFile) { return(false); } if (_input.Index + _lookAheadPosition >= _input.Count) { _endOfFile = true; return(false); } IToken token = _input.LT(-1 - _lookBehindPosition); if (token == null) { _endOfFile = true; return(false); } int symbol = token.Type; int symbolPosition = token.TokenIndex; 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.SourceState, null, null, this); ContextFrame endContext = new ContextFrame(transition.SourceState, null, null, this); initialContexts.Add(new InterpretTrace(startContext, endContext)); } _contexts.AddRange(initialContexts); } 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.EndContext.State.Id); StepForward(contexts, states, context, symbol, symbolPosition, PreventContextType.None); states.Clear(); } bool success = false; if (contexts.Count > 0) { _contexts.AddRange(contexts); if (TrackBoundedContexts) { _boundedEndContexts.UnionWith(_contexts.Where(i => i.BoundedEnd)); } success = true; } else { _contexts.AddRange(existing); } long nfaUpdateTime = updateTimer.ElapsedMilliseconds; if (success) { _lookAheadPosition++; } if (!success) { _failedForward = 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); }
public virtual bool Equals(InterpretTrace x, InterpretTrace y) { if (object.ReferenceEquals(x, y)) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x.Transitions, y.Transitions)) { return(true); } if (x.Transitions.Count == 0) { return(y.Transitions.Count == 0); } if (y.Transitions.Count == 0) { return(false); } // unique on the end context, the last transition's source state, and the end position for (ContextFrame xframe = x.EndContext, yframe = y.EndContext; true; xframe = xframe.Parent, yframe = yframe.Parent) { if (xframe == null || yframe == null) { if (xframe != null || yframe != null) { return(false); } break; } if (xframe.Context != yframe.Context) { return(false); } } InterpretTraceTransition lastx = x.Transitions.Last.Value; InterpretTraceTransition lasty = y.Transitions.Last.Value; if (!EqualityComparer <State> .Default.Equals(lastx.Transition.SourceState, lasty.Transition.SourceState)) { return(false); } InterpretTraceTransition lastxmatch = x.Transitions.LastOrDefault(i => i.Transition.IsMatch); InterpretTraceTransition lastymatch = y.Transitions.LastOrDefault(i => i.Transition.IsMatch); if (lastxmatch == null) { return(lastymatch == null); } if (lastymatch == null) { return(false); } if (lastxmatch.TokenIndex != lastymatch.TokenIndex) { return(false); } return(true); }