示例#1
0
        protected virtual void GetRuleStates(StateOptimizer optimizer, RuleBinding ruleName, State state, Dictionary <int, RuleBinding> stateRules)
        {
            if (stateRules.ContainsKey(state.Id))
            {
                return;
            }

            stateRules[state.Id] = ruleName;

            foreach (var transition in state.OutgoingTransitions)
            {
                if (transition is PopContextTransition)
                {
                    continue;
                }

                PushContextTransition contextTransition = transition as PushContextTransition;
                if (contextTransition != null)
                {
                    foreach (var popTransition in optimizer.GetPopContextTransitions(contextTransition))
                    {
                        GetRuleStates(optimizer, ruleName, popTransition.TargetState, stateRules);
                    }
                }
                else
                {
                    GetRuleStates(optimizer, ruleName, transition.TargetState, stateRules);
                }
            }
        }
        private void GetSiblingStates(State currentState, HashSet <State> states)
        {
            foreach (var transition in currentState.OutgoingTransitions)
            {
                if (transition.IsContext)
                {
                    PushContextTransition pushContextTransition = transition as PushContextTransition;
                    if (pushContextTransition == null)
                    {
                        continue;
                    }

                    foreach (var popTransition in Optimizer.GetPopContextTransitions(pushContextTransition))
                    {
                        if (states.Add(popTransition.TargetState))
                        {
                            GetSiblingStates(popTransition.TargetState, states);
                        }
                    }
                }
                else if (states.Add(transition.TargetState))
                {
                    GetSiblingStates(transition.TargetState, states);
                }
            }
        }
示例#3
0
        private bool AddRecursivePushTransitions([NotNull] HashSet <State> visited, [NotNull] State currentState, Transition effectiveTransition, [NotNull] List <int> contexts, StateOptimizer optimizer)
        {
            Debug.Assert(visited != null);
            Debug.Assert(currentState != null);
            Debug.Assert(contexts != null);

            bool foundRecursive = false;

            foreach (var transition in currentState.OutgoingTransitions.Where(i => !i.IsRecursive && (i.IsEpsilon || (i is PushContextTransition))).ToArray())
            {
                ContextTransition contextTransition = transition as ContextTransition;
                try
                {
                    if (contextTransition != null)
                    {
                        contexts.AddRange(contextTransition.ContextIdentifiers);
                    }

                    if (transition.TargetState == this)
                    {
                        foundRecursive = true;

                        if (contexts.Count == 0)
                        {
                            Trace.WriteLine(string.Format("State {0} is self-recursive.", this.Id));
                            continue;
                        }

                        PushContextTransition recursive = new PushContextTransition(this, contexts);
                        recursive.IsRecursive = true;
                        AddTransitionInternal(recursive, optimizer);
                        continue;
                    }

                    if (!visited.Add(transition.TargetState))
                    {
                        continue;
                    }

                    try
                    {
                        AddRecursivePushTransitions(visited, transition.TargetState, MergeTransitions(effectiveTransition, transition), contexts, optimizer);
                    }
                    finally
                    {
                        visited.Remove(transition.TargetState);
                    }
                }
                finally
                {
                    if (contextTransition != null)
                    {
                        contexts.RemoveRange(contexts.Count - contextTransition.ContextIdentifiers.Count, contextTransition.ContextIdentifiers.Count);
                    }
                }
            }

            return(foundRecursive);
        }
        private IEnumerable <State> GetEnclosedStates(PushContextTransition transition)
        {
            HashSet <State> states = new HashSet <State>(ObjectReferenceEqualityComparer <State> .Default);

            states.Add(transition.TargetState);
            GetSiblingStates(transition.TargetState, states);
            return(states);
        }
        public static Nfa Rule(RuleBinding ruleBinding)
        {
            State startState = new State();
            State endState   = new State();

            PushContextTransition push = new PushContextTransition(ruleBinding.StartState, startState.Id);
            PopContextTransition  pop  = new PopContextTransition(endState, startState.Id);

            startState.AddTransition(push);
            ruleBinding.EndState.AddTransition(pop);

            return(new Nfa(startState, endState));
        }
示例#6
0
        internal void RemoveTransition(Transition transition)
        {
            Contract.Requires <ArgumentNullException>(transition != null, "transition");

            RemoveReachableTransition(transition);

            PushContextTransition pushContextTransition = transition as PushContextTransition;

            if (pushContextTransition != null)
            {
                int context = pushContextTransition.ContextIdentifiers[0];
                HashSet <PushContextTransition> transitions = _pushContextTransitions[context];
                transitions.Remove(pushContextTransition);
            }

            PopContextTransition popContextTransition = transition as PopContextTransition;

            if (popContextTransition != null)
            {
                int context = popContextTransition.ContextIdentifiers.Last();
                HashSet <PopContextTransition> transitions = _popContextTransitions[context];
                transitions.Remove(popContextTransition);
            }
        }
示例#7
0
        internal void AddTransition(Transition transition)
        {
            Contract.Requires <ArgumentNullException>(transition != null, "transition");

            AddReachableTransition(transition);

            PushContextTransition pushContextTransition = transition as PushContextTransition;

            if (pushContextTransition != null)
            {
                int context = pushContextTransition.ContextIdentifiers[0];
                HashSet <PushContextTransition> transitions;
                if (!_pushContextTransitions.TryGetValue(context, out transitions))
                {
                    transitions = new HashSet <PushContextTransition>(ObjectReferenceEqualityComparer <Transition> .Default);
                    _pushContextTransitions[context] = transitions;
                }

                transitions.Add(pushContextTransition);
            }

            PopContextTransition popContextTransition = transition as PopContextTransition;

            if (popContextTransition != null)
            {
                int context = popContextTransition.ContextIdentifiers.Last();
                HashSet <PopContextTransition> transitions;
                if (!_popContextTransitions.TryGetValue(context, out transitions))
                {
                    transitions = new HashSet <PopContextTransition>(ObjectReferenceEqualityComparer <Transition> .Default);
                    _popContextTransitions[context] = transitions;
                }

                transitions.Add(popContextTransition);
            }
        }
示例#8
0
        internal void RemoveTransition([NotNull] Transition transition)
        {
            Requires.NotNull(transition, nameof(transition));

            RemoveReachableTransition(transition);

            PushContextTransition pushContextTransition = transition as PushContextTransition;

            if (pushContextTransition != null)
            {
                int context = pushContextTransition.ContextIdentifiers[0];
                HashSet <PushContextTransition> transitions = _pushContextTransitions[context];
                transitions.Remove(pushContextTransition);
            }

            PopContextTransition popContextTransition = transition as PopContextTransition;

            if (popContextTransition != null)
            {
                int context = popContextTransition.ContextIdentifiers.Last();
                HashSet <PopContextTransition> transitions = _popContextTransitions[context];
                transitions.Remove(popContextTransition);
            }
        }
示例#9
0
 private IEnumerable<State> GetEnclosedStates(PushContextTransition transition)
 {
     HashSet<State> states = new HashSet<State>(ObjectReferenceEqualityComparer<State>.Default);
     states.Add(transition.TargetState);
     GetSiblingStates(transition.TargetState, states);
     return states;
 }
示例#10
0
        private Transition MergeTransitions(Transition first, Transition second)
        {
            Contract.Requires(first != null);
            Contract.Requires(second != null);

            Contract.Ensures(Contract.Result <Transition>().SourceState == null);
            Contract.Ensures(Contract.Result <Transition>().IsRecursive == second.IsRecursive);

            Contract.Assert(!first.IsRecursive);
            Contract.Assert(first.IsEpsilon || !second.IsRecursive);

            if (first.IsMatch)
            {
                if (!second.IsEpsilon)
                {
                    throw new InvalidOperationException();
                }

                MatchRangeTransition matchRangeTransition = first as MatchRangeTransition;
                if (matchRangeTransition != null)
                {
                    return(new MatchRangeTransition(second.TargetState, matchRangeTransition.Range));
                }

                throw new NotImplementedException("Unknown match transition type.");
            }

            if (first.IsEpsilon)
            {
                if (second.IsEpsilon)
                {
                    return(new EpsilonTransition(second.TargetState));
                }

                MatchRangeTransition matchRangeTransition = second as MatchRangeTransition;
                if (matchRangeTransition != null)
                {
                    return(new MatchRangeTransition(second.TargetState, matchRangeTransition.Range));
                }

                PopContextTransition popContextTransition = second as PopContextTransition;
                if (popContextTransition != null)
                {
                    var transition = new PopContextTransition(second.TargetState, popContextTransition.ContextIdentifiers);
                    //transition.PushTransitions.UnionWith(popContextTransition.PushTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PushTransitions, i => i.SourceState != null));
                    return(transition);
                }

                PushContextTransition pushContextTransition = second as PushContextTransition;
                if (pushContextTransition != null)
                {
                    var transition = new PushContextTransition(second.TargetState, pushContextTransition.ContextIdentifiers);
                    //transition.PopTransitions.UnionWith(pushContextTransition.PopTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PopTransitions, i => i.SourceState != null));
                    return(transition);
                }

                throw new NotSupportedException();
            }

            PopContextTransition popFirst = first as PopContextTransition;

            if (popFirst != null)
            {
                if (second.IsEpsilon)
                {
                    var transition = new PopContextTransition(second.TargetState, popFirst.ContextIdentifiers);
                    //transition.PushTransitions.UnionWith(popFirst.PushTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PushTransitions, i => i.SourceState != null));
                    return(transition);
                }

                PopContextTransition popSecond = second as PopContextTransition;
                if (popSecond != null)
                {
                    var transition = new PopContextTransition(popSecond.TargetState, popFirst.ContextIdentifiers.Concat(popSecond.ContextIdentifiers));
                    ////transition.PushTransitions.UnionWith(popFirst.PushTransitions);
                    //transition.PushTransitions.UnionWith(popSecond.PushTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PushTransitions, i => i.SourceState != null));
                    return(transition);
                }

                if (second is PushContextTransition)
                {
                    throw new InvalidOperationException();
                }

                if (second.IsMatch)
                {
                    throw new NotSupportedException();
                }

                throw new NotImplementedException();
            }

            PushContextTransition pushFirst = first as PushContextTransition;

            if (pushFirst != null)
            {
                if (second.IsEpsilon)
                {
                    var transition = new PushContextTransition(second.TargetState, pushFirst.ContextIdentifiers);
                    //transition.PopTransitions.UnionWith(pushFirst.PopTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PopTransitions, i => i.SourceState != null));
                    return(transition);
                }

                PushContextTransition pushSecond = second as PushContextTransition;
                if (pushSecond != null)
                {
                    var transition = new PushContextTransition(pushSecond.TargetState, pushFirst.ContextIdentifiers.Concat(pushSecond.ContextIdentifiers));
                    //transition.PopTransitions.UnionWith(pushFirst.PopTransitions);
                    ////transition.PopTransitions.UnionWith(pushSecond.PopTransitions);
                    //Contract.Assert(Contract.ForAll(transition.PopTransitions, i => i.SourceState != null));
                    return(transition);
                }

                if (second is PopContextTransition)
                {
                    throw new InvalidOperationException();
                }

                if (second.IsMatch)
                {
                    throw new NotSupportedException();
                }

                throw new NotImplementedException();
            }

            throw new NotImplementedException();
        }
示例#11
0
        internal void AddTransitionInternal(Transition transition, StateOptimizer optimizer)
        {
            Contract.Requires(transition != null);
            Contract.Requires(transition.SourceState == null);
#if ALL_CHECKS
            Contract.Requires(!OutgoingTransitions.Contains(transition));
            Contract.Requires(!transition.TargetState.IncomingTransitions.Contains(transition));
#endif

            if (IsRecursiveAnalysisComplete && !transition.IsMatch && transition.TargetState == this && !transition.IsRecursive)
            {
                throw new InvalidOperationException();
            }

            PopContextTransition  popContextTransition  = transition as PopContextTransition;
            PushContextTransition pushContextTransition = transition as PushContextTransition;

#if false
            if (popContextTransition != null && !transition.IsRecursive)
            {
                foreach (var recursive in OutgoingTransitions.OfType <PopContextTransition>().Where(i => i.IsRecursive))
                {
                    if (popContextTransition.ContextIdentifiers.Take(recursive.ContextIdentifiers.Count).SequenceEqual(recursive.ContextIdentifiers))
                    {
                        if (popContextTransition.ContextIdentifiers.Count > recursive.ContextIdentifiers.Count)
                        {
                            throw new InvalidOperationException();
                        }
                    }
                }
            }
#endif

            if (_outgoingTransitions.Count > 10 && !(_outgoingTransitions is ISet <Transition>))
            {
                _outgoingTransitions = new HashSet <Transition>(_outgoingTransitions, ObjectReferenceEqualityComparer <Transition> .Default);
            }

#if false
            if (transition.IsContext && transition.IsRecursive)
            {
                PopContextTransition first = transition as PopContextTransition;
                if (first != null)
                {
                    foreach (var existing in OutgoingTransitions.OfType <PopContextTransition>().ToArray())
                    {
                        if (existing.TargetState != transition.TargetState)
                        {
                            continue;
                        }

                        if (first.ContextIdentifiers.Take(existing.ContextIdentifiers.Count).SequenceEqual(existing.ContextIdentifiers))
                        {
                            RemoveTransitionInternal(existing, optimizer);
                        }
                    }
                }

                PushContextTransition second = transition as PushContextTransition;
                if (second != null)
                {
                    foreach (var existing in OutgoingTransitions.OfType <PushContextTransition>().ToArray())
                    {
                        if (existing.TargetState != transition.TargetState)
                        {
                            continue;
                        }

                        if (second.ContextIdentifiers.Take(existing.ContextIdentifiers.Count).SequenceEqual(existing.ContextIdentifiers))
                        {
                            RemoveTransitionInternal(existing, optimizer);
                        }
                    }
                }
            }
#endif

            OutgoingTransitions.Add(transition);

            if (transition.TargetState.IncomingTransitions.Count > 10 && !(transition.TargetState.IncomingTransitions is ISet <Transition>))
            {
                transition.TargetState._incomingTransitions = new HashSet <Transition>(transition.TargetState._incomingTransitions, ObjectReferenceEqualityComparer <Transition> .Default);
            }

            transition.TargetState.IncomingTransitions.Add(transition);
            transition.SourceState = this;

            if (optimizer != null)
            {
                optimizer.AddTransition(transition);
            }

            if (popContextTransition != null)
            {
                //if (optimizer != null)
                //    popContextTransition.PushTransitions.UnionWith(optimizer.GetPushContextTransitions(popContextTransition.ContextIdentifiers.Last()));

                //foreach (var pushTransition in popContextTransition.PushTransitions)
                //{
                //    Contract.Assert(pushTransition.ContextIdentifiers.First() == popContextTransition.ContextIdentifiers.Last());
                //    Contract.Assert(pushTransition.SourceState != null);
                //    pushTransition.PopTransitions.Add(popContextTransition);
                //}

#if ALL_CHECKS
                Contract.Assert(Contract.ForAll(OutgoingTransitions.OfType <PushContextTransition>(), i => i.ContextIdentifiers.Last() != popContextTransition.ContextIdentifiers.First() || popContextTransition.PushTransitions.Contains(i)));
#endif
            }
            else if (pushContextTransition != null)
            {
                //if (optimizer != null)
                //    pushContextTransition.PopTransitions.UnionWith(optimizer.GetPopContextTransitions(pushContextTransition.ContextIdentifiers[0]));

                //foreach (var popTransition in pushContextTransition.PopTransitions)
                //{
                //    Contract.Assert(popTransition.ContextIdentifiers.Last() == pushContextTransition.ContextIdentifiers.First());
                //    Contract.Assert(popTransition.SourceState != null);
                //    popTransition.PushTransitions.Add(pushContextTransition);
                //}

#if ALL_CHECKS
                Contract.Assert(Contract.ForAll(OutgoingTransitions.OfType <PopContextTransition>(), i => i.ContextIdentifiers.Last() != pushContextTransition.ContextIdentifiers.First() || pushContextTransition.PopTransitions.Contains(i)));
#endif
            }

            _followSet          = null;
            _isForwardRecursive = null;
            transition.TargetState._sourceSet           = null;
            transition.TargetState._isBackwardRecursive = null;
        }
示例#12
0
        public static Nfa Rule(RuleBinding ruleBinding)
        {
            State startState = new State();
            State endState = new State();

            PushContextTransition push = new PushContextTransition(ruleBinding.StartState, startState.Id);
            PopContextTransition pop = new PopContextTransition(endState, startState.Id);

            startState.AddTransition(push);
            ruleBinding.EndState.AddTransition(pop);

            return new Nfa(startState, endState);
        }
示例#13
0
 internal IEnumerable <PopContextTransition> GetPopContextTransitions(PushContextTransition pushContextTransition)
 {
     Contract.Requires <ArgumentNullException>(pushContextTransition != null, "pushContextTransition");
     Contract.Ensures(Contract.Result <IEnumerable <PopContextTransition> >() != null);
     return(GetPopContextTransitions(pushContextTransition.ContextIdentifiers[0]));
 }
 internal IEnumerable<PopContextTransition> GetPopContextTransitions(PushContextTransition pushContextTransition)
 {
     Contract.Requires<ArgumentNullException>(pushContextTransition != null, "pushContextTransition");
     Contract.Ensures(Contract.Result<IEnumerable<PopContextTransition>>() != null);
     return GetPopContextTransitions(pushContextTransition.ContextIdentifiers[0]);
 }
示例#15
0
 internal IEnumerable <PopContextTransition> GetPopContextTransitions([NotNull] PushContextTransition pushContextTransition)
 {
     Requires.NotNull(pushContextTransition, nameof(pushContextTransition));
     return(GetPopContextTransitions(pushContextTransition.ContextIdentifiers[0]));
 }