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);
                }
            }
        }
Exemplo n.º 3
0
        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);
                    }
                }
            }
        }
Exemplo n.º 4
0
        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.");
        }
Exemplo n.º 5
0
        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);
                    }
                }
            }
        }