public LrItemsDfa( IEnumerable <ProductionItemSet <TTokenKind> > states, IEnumerable <Symbol> alphabet, IEnumerable <Transition <Symbol, ProductionItemSet <TTokenKind> > > transitions, ProductionItemSet <TTokenKind> startState, IEnumerable <ProductionItemSet <TTokenKind> > acceptStates) { _originalStates = states.ToArray(); MaxState = _originalStates.Length; // 0,1,2,...,maxState, where dead state is at index zero // renaming all states to integers var indexMap = new Dictionary <ProductionItemSet <TTokenKind>, int>(MaxState); // dead state excluded here int stateIndex = 1; foreach (ProductionItemSet <TTokenKind> state in _originalStates) { indexMap.Add(state, stateIndex); stateIndex += 1; } _indexToAlphabet = alphabet.ToArray(); _alphabetToIndex = new Dictionary <Symbol, int>(); for (int i = 0; i < _indexToAlphabet.Length; i++) { _alphabetToIndex[_indexToAlphabet[i]] = i; } StartState = indexMap[startState]; _acceptStates = new HashSet <int>(); foreach (ProductionItemSet <TTokenKind> state in acceptStates) { _acceptStates.Add(indexMap[state]); } _nextState = new int[MaxState + 1, _alphabetToIndex.Count]; foreach (var move in transitions) { int source = indexMap[move.SourceState]; int target = indexMap[move.TargetState]; _nextState[source, _alphabetToIndex[move.Label]] = target; } }
/// <summary> /// Create Deterministic Finite Automaton by lazy form of subset construction (Rabin and Scott, ) /// </summary> /// <returns>Deterministic Finite Automaton created by lazy form of subset construction</returns> public LrItemsDfa <TTokenKind> ToDfa() { // The subset construction is an example of a fixed-point computation, where an application of a // monotone function to some collection of sets drawn from a domain whose structure is known is // performed iteratively. The computation will terminate when an iteration step produces a state // where further iteration produces the same answer — a “fixed point” in the space of successive // iterates. // // For the subset construction, the domain is the power set of all possible subsets of the NFA states. // The while loop adds elements (subsets) to Q; it cannot remove an element from Q. We can view // the while loop as a monotone increasing function f, which means that for a set x, f(x) ≥ x. (The // comparison operator ≥ is ⊇.) Since Q can have at most 2^N distinct elements, the while loop can iterate // at most 2^N times. It may, of course, reach a fixed point and halt more quickly than that. var newStartState = EpsilonClose(StartState.AsSingletonEnumerable()); var newAcceptStates = new HashSet <ProductionItemSet <TTokenKind> >(); var newTransitions = new List <Transition <Symbol, ProductionItemSet <TTokenKind> > >(); var newStates = new InsertionOrderedSet <ProductionItemSet <TTokenKind> > { newStartState }; // Lazy form of Subset Construction where only reachable nodes // are added to the following work list of marked subsets var markedVisitedStates = new Queue <ProductionItemSet <TTokenKind> >(); // work list that preserves insertion order markedVisitedStates.Enqueue(newStartState); while (markedVisitedStates.Count != 0) { // subset S ProductionItemSet <TTokenKind> subsetSourceState = markedVisitedStates.Dequeue(); if (subsetSourceState.Overlaps(GetAcceptStates())) { newAcceptStates.Add(subsetSourceState); } // For all non-epsilon labels foreach (var label in GetAlphabet()) { // subset T var subsetTargetState = new Set <ProductionItem <TTokenKind> >(); // kernel items: For all s in S, add all non-epsilon transitions (s, label) → t to T foreach (ProductionItem <TTokenKind> s in subsetSourceState) { subsetTargetState.AddRange(Delta(Transition.FromPair(s, label))); } // Ignore empty subset (implicit transition to dead state in this case) if (subsetTargetState.Count == 0) { continue; } // Closure Items: Epsilon-close all T such that (S, label) → T var closure = EpsilonClose(subsetTargetState); if (!newStates.Contains(closure)) { newStates.Add(closure); markedVisitedStates.Enqueue(closure); } // Add (S, label) → T transition newTransitions.Add(Transition.Move(subsetSourceState, label, closure)); } } return(new LrItemsDfa <TTokenKind>(newStates, GetAlphabet(), newTransitions, newStartState, newAcceptStates)); }
public bool Equals(ProductionItemSet <TTokenKind> other) { return(other != null && _kernelItems.SetEquals(other.KernelItems)); }