예제 #1
0
        public FSA <TValue> CreateRawFsa(AstRootNode root, ORegexOptions options)
        {
            var result = new FSA <TValue>(root.CaptureGroupNames[0])
            {
                CaptureNames = root.CaptureGroupNames
            };
            var start = result.NewState();
            var end   = result.NewState();

            Evaluate(start, end, result, root, options);
            result.AddFinal(end);
            result.AddStart(start);
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Subset machine that employs the powerset construction or subset construction algorithm.
        /// It creates a DFA that recognizes the same language as the given NFA.
        /// </summary>
        private static FSA <TValue> ToDfa(FSA <TValue> fsa)
        {
            FSA <TValue> dfa = new FSA <TValue>(fsa.Name)
            {
                ExactBegin   = fsa.ExactBegin,
                ExactEnd     = fsa.ExactEnd,
                CaptureNames = fsa.CaptureNames,
            };

            // Sets of NFA states which is represented by some DFA state
            var markedStates   = new HashSet <Set <int> >();
            var unmarkedStates = new HashSet <Set <int> >();

            // Gives a number to each state in the DFA
            var dfaStateNum = new Dictionary <Set <int>, int>();

            var nfaInitial = fsa.Q0.ToSet();

            // Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states
            // and it's unmarked.
            var first = EpsilonClosure(fsa, nfaInitial);

            unmarkedStates.Add(first);

            // The initial dfa state
            int dfaInitial = dfa.NewState();

            dfaStateNum[first] = dfaInitial;
            dfa.AddStart(dfaInitial);

            while (unmarkedStates.Count != 0)
            {
                // Takes out one unmarked state and posteriorly mark it.
                var aState = unmarkedStates.First();

                // Removes from the unmarked set.
                unmarkedStates.Remove(aState);

                // Inserts into the marked set.
                markedStates.Add(aState);

                // If this state contains the NFA's final state, add it to the DFA's set of
                // final states.
                if (fsa.F.Any(x => aState.Contains(x)))
                {
                    dfa.AddFinal(dfaStateNum[aState]);
                }

                // For each input symbol the NFA knows...

                foreach (var current in fsa.Sigma)
                {
                    // Next state
                    var next = EpsilonClosure(fsa, fsa.Move(aState, current));

                    if (next.Count > 0)
                    {
                        // If we haven't examined this state before, add it to the unmarkedStates,
                        // and make up a new number for it.
                        if (!unmarkedStates.Contains(next) && !markedStates.Contains(next))
                        {
                            unmarkedStates.Add(next);
                            dfaStateNum.Add(next, dfa.NewState());
                        }

                        var from      = dfaStateNum[aState];
                        var to        = dfaStateNum[next];
                        var condition = current;

                        dfa.AddTransition(from, condition, to);
                    }
                }
            }

            return(dfa);
        }