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;
            }
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
 public bool Equals(ProductionItemSet <TTokenKind> other)
 {
     return(other != null && _kernelItems.SetEquals(other.KernelItems));
 }