Ejemplo n.º 1
0
        /// <summary>
        /// Converts NFA to DFA using "Subset Construction"
        /// </summary>
        /// <param name="stateStartNfa">Starting state of NFA</param>
        /// <param name="setMasterDfa">Contains set of all DFA states when this function returns</param>
        /// <returns>Starting state of DFA</returns>
        public static State ConvertToDfa(State stateStartNfa)
        {
            if (stateStartNfa == null)
            {
                throw new ArgumentNullException(nameof(stateStartNfa));
            }

            HashSet <string> setAllInput = new HashSet <string>();
            HashSet <State>  setAllState = new HashSet <State>();

            GetAllStateAndInput(stateStartNfa, setAllState, setAllInput);
            setAllInput.Remove(MetaSymbol.EPSILON);

            NfaToDfaHelper  helper       = new NfaToDfaHelper();
            HashSet <State> setMove      = null;
            HashSet <State> setE_closure = null;

            // first, we get E_Closure of the start state of NFA ( just following the algorithm)
            setE_closure = E_Closure(stateStartNfa);

            State stateStartDfa = new State();              // create a new DFA state to represent the above E_Closure

            // NOTE:
            // we keep track of the NFA E_Closure and the DFA state that represent the E_Closure.
            // we maintain a relationship between the NFA E_Closure and DFA state that represents the NFA E_Closure.
            // all these are done in the NfaToDfaHelper class.

            if (IsAcceptingGroup(setE_closure))
            {
                stateStartDfa.AcceptingState = true;
            }

            helper.AddDfaState(stateStartDfa, setE_closure);
            // please see "subset construction" algorithm
            // for clear understanding

            State           stateT = null;
            HashSet <State> setT   = null;
            State           stateU = null;

            while ((stateT = helper.GetNextUnmarkedDfaState()) != null)
            {
                helper.Mark(stateT);                   // flag it to indicate that we have processed this state.

                // the DFA state stateT represents a set of NFA E_Closure.
                // so, we retrieve the E_Closure.
                setT = helper.GetE_ClosureByDfaState(stateT);

                foreach (string str in setAllInput)
                {
                    setMove = Move(setT, str);

                    if (setMove.Count > 0)
                    {
                        setE_closure = E_Closure(setMove);

                        stateU = helper.FindDfaStateByE_Closure(setE_closure);

                        if (stateU == null)                         // so set setEnclosure must be a new one and we should crate a new DFA state
                        {
                            stateU = new State();
                            if (IsAcceptingGroup(setE_closure))
                            {
                                stateU.AcceptingState = true;
                            }
                            helper.AddDfaState(stateU, setE_closure);                              // add new state (as unmarked by default)
                        }

                        stateT.AddTransition(str, stateU);
                    }
                }          // end of foreach..loop
            }              // end of while..loop

            return(stateStartDfa);
        }          // end of ConvertToDfa method
Ejemplo n.º 2
0
        }  // end of CreateNfa method

        /// <summary>
        /// Converts NFA to DFA using "Subset Construction"
        /// </summary>
        /// <param name="stateStartNfa">Starting state of NFA</param>
        /// <param name="setMasterDfa">Contains set of all DFA states when this function returns</param>
        /// <returns>Starting state of DFA</returns>
        private State ConvertToDfa(State stateStartNfa)
        {
            //Subset Construction算法

            Set setAllInput = new Set();
            Set setAllState = new Set();

            GetAllStateAndInput(stateStartNfa, setAllState, setAllInput);
            setAllInput.RemoveElement(MetaSymbol.EPSILON);

            NfaToDfaHelper helper      = new NfaToDfaHelper();
            Set            setMove     = null;
            Set            setEclosure = null;

            // first, we get Eclosure of the start state of NFA ( just following the algoritham)
            setEclosure = Eclosure(stateStartNfa);
            State stateStartDfa = new State();  // create a new DFA state to represent the above Eclosure

            // NOTE:
            // we keep track of the NFA Eclosure and the DFA state that represent the Eclosure.
            // we maintain a relationship between the NFA Eclosure and DFA state that represents the NFA Eclosure.
            // all these are done in the NfaToDfaHelper class.

            if (IsAcceptingGroup(setEclosure) == true)
            {
                stateStartDfa.AcceptingState = true;
            }

            helper.AddDfaState(stateStartDfa, setEclosure);

            string sInputSymbol = String.Empty; // dummy

            // please see "subset construction" algoritham
            // for clear understanding

            State stateT = null;
            Set   setT   = null;
            State stateU = null;

            while ((stateT = helper.GetNextUnmarkedDfaState()) != null)
            {
                helper.Mark(stateT);   // flag it to indicate that we have processed this state.

                // the DFA state stateT represents a set of NFA Eclosure.
                // so, we retrieve the Eclosure.
                setT = helper.GetEclosureByDfaState(stateT);

                foreach (object obj in setAllInput)
                {
                    sInputSymbol = obj.ToString();

                    setMove = Move(setT, sInputSymbol);

                    if (setMove.IsEmpty() == false)
                    {
                        setEclosure = Eclosure(setMove);

                        stateU = helper.FindDfaStateByEclosure(setEclosure);

                        if (stateU == null) // so set setEclosure must be a new one and we should crate a new DFA state
                        {
                            stateU = new State();
                            if (IsAcceptingGroup(setEclosure) == true)
                            {
                                stateU.AcceptingState = true;
                            }

                            helper.AddDfaState(stateU, setEclosure);  // add new state (as unmarked by default)
                        }

                        stateT.AddTransition(sInputSymbol, stateU);
                    }
                } // end of foreach..loop
            }     // end of while..loop

            return(stateStartDfa);
        }  // end of ConverToDfa method