/// <summary> /// Adds an incoming transition to the place. This is usually called when you add a <see cref="Transition"/> to the net. /// </summary> /// <param Name="transition">The incoming transition.</param> public void AppendIncomingTransition(Transition transition) { if (!IncomingTransitions.Contains(transition)) { IncomingTransitions.Add(transition); } }
public void RemoveExtraEpsilonTransitions(StateOptimizer optimizer, bool isStartState) { if (OutgoingTransitions.Count == 1 && OutgoingTransitions.First().IsEpsilon) { Transition epsilon = OutgoingTransitions.First(); foreach (var incoming in IncomingTransitions.ToArray()) { State sourceState = incoming.SourceState; sourceState.RemoveTransitionInternal(incoming, optimizer); sourceState.AddTransitionInternal(MergeTransitions(incoming, epsilon), optimizer); } if (!isStartState) { RemoveTransitionInternal(epsilon, optimizer); } } if (IncomingTransitions.Count == 1 && IncomingTransitions.First().IsEpsilon) { Transition epsilon = IncomingTransitions.First(); State sourceState = epsilon.SourceState; foreach (var outgoing in OutgoingTransitions.ToArray()) { if (!isStartState) { this.RemoveTransitionInternal(outgoing, optimizer); } sourceState.AddTransitionInternal(MergeTransitions(epsilon, outgoing), optimizer); } epsilon.SourceState.RemoveTransitionInternal(epsilon, optimizer); } }
public IntervalSet GetSourceSet(PreventContextType preventContextType) { if (_sourceSet != null && _sourceSet[(int)preventContextType] != null) { return(_sourceSet[(int)preventContextType]); } IntervalSet[] sets = _sourceSet ?? new IntervalSet[Enum.GetValues(typeof(PreventContextType)).Cast <int>().Max() + 1]; IntervalSet set = new IntervalSet(); var queue = new Queue <Tuple <Transition, PreventContextType> >(IncomingTransitions.Select(i => Tuple.Create(i, preventContextType))); var comparer = new TupleEqualityComparer <Transition, PreventContextType>(ObjectReferenceEqualityComparer <Transition> .Default, null); var visited = new HashSet <Tuple <Transition, PreventContextType> >(queue, comparer); while (queue.Count > 0) { var pair = queue.Dequeue(); Transition transition = pair.Item1; PreventContextType nextPreventContextType = pair.Item2; if (transition.SourceState.IsOptimized) { switch (nextPreventContextType) { 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; } } if (transition.IsEpsilon || transition.IsContext) { if (transition.IsContext) { nextPreventContextType = PreventContextType.None; if (transition is PushContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } if (transition.SourceState._sourceSet != null && transition.SourceState._sourceSet[(int)nextPreventContextType] != null) { set.UnionWith(transition.SourceState._sourceSet[(int)nextPreventContextType]); } else { foreach (var incoming in transition.SourceState.IncomingTransitions) { var nextPair = Tuple.Create(incoming, nextPreventContextType); if (visited.Add(nextPair)) { queue.Enqueue(Tuple.Create(incoming, nextPreventContextType)); } } } } else { set.UnionWith(transition.MatchSet); } } _sourceSet = sets; _sourceSet[(int)preventContextType] = set; return(set); }