private void StepForward(ICollection <InterpretTrace> result, ICollection <int> states, InterpretTrace context, int symbol, int symbolPosition, PreventContextType preventContextType) { foreach (var transition in context.EndContext.State.OutgoingTransitions) { if (transition.IsContext) { PopContextTransition popContextTransition = transition as PopContextTransition; if (popContextTransition != null && context.EndContext.Parent != null) { if (popContextTransition.ContextIdentifiers[0] != context.EndContext.Parent.Context) { continue; } } switch (preventContextType) { 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; } } InterpretTrace step; if (context.TryStepForward(transition, symbol, symbolPosition, out step)) { if (transition.IsMatch) { result.Add(step); continue; } bool recursive = transition.TargetState.IsForwardRecursive; bool addRecursive = false; if (recursive) { addRecursive = !states.Contains(transition.TargetState.Id); if (!addRecursive && (!(transition is PopContextTransition) || context.EndContext.Parent == null)) { continue; } } if (addRecursive) { states.Add(transition.TargetState.Id); } PreventContextType nextPreventContextType = PreventContextType.None; if (context.EndContext.State.IsOptimized) { if (transition is PushContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } StepForward(result, states, step, symbol, symbolPosition, nextPreventContextType); if (addRecursive) { states.Remove(transition.TargetState.Id); } } } }
private void StepBackward(ICollection <InterpretTrace> result, ICollection <int> states, InterpretTrace context, int symbol, int symbolPosition, PreventContextType preventContextType) { foreach (var transition in context.StartContext.State.IncomingTransitions) { if (transition.SourceState.IsOptimized) { switch (preventContextType) { 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; } } InterpretTrace step; if (context.TryStepBackward(transition, symbol, symbolPosition, out step)) { if (transition.IsMatch) { result.Add(step); continue; } bool recursive = transition.SourceState.IsBackwardRecursive; if (recursive && states.Contains(transition.SourceState.Id)) { // TODO: check postfix rule continue; } if (recursive) { states.Add(transition.SourceState.Id); } PreventContextType nextPreventContextType = PreventContextType.None; if (context.StartContext.State.IsOptimized) { if (transition is PushContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } StepBackward(result, states, step, symbol, symbolPosition, nextPreventContextType); if (recursive) { states.Remove(transition.SourceState.Id); } } } }