Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
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.");
        }
Ejemplo n.º 3
0
 public InterpretTrace(ContextFrame startContext, ContextFrame endContext)
     : this(startContext, endContext, EmptyTransitions, false, false, false)
 {
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }