Beispiel #1
0
        /// <summary>
        /// Builds a star (kleene closure) of nfa (nfa*)
        /// How this is done: First will come the new initial state, then NFA, then the
        /// new final state
        /// </summary>
        /// <param name="nfa"></param>
        /// <returns></returns>
        public static NFA BuildNFAStar(NFA nfa)
        {
            // Makes room for the new initial state
            nfa.ShiftStates(1);

            // Makes room for the new final state
            nfa.AppendEmptyState();

            // Adds new transitions
            nfa.AddTrans(nfa.final, nfa.initial, (char)Constants.Epsilon);
            nfa.AddTrans(0, nfa.initial, (char)Constants.Epsilon);
            nfa.AddTrans(nfa.final, nfa.size - 1, (char)Constants.Epsilon);
            nfa.AddTrans(0, nfa.size - 1, (char)Constants.Epsilon);

            nfa.initial = 0;
            nfa.final   = nfa.size - 1;

            return(nfa);
        }
Beispiel #2
0
        /// <summary>
        /// Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
        /// </summary>
        /// <param name="nfa1"></param>
        /// <param name="nfa2"></param>
        /// <returns></returns>
        public static NFA BuildNFAConcat(NFA nfa1, NFA nfa2)
        {
            // How this is done: First will come nfa1, then nfa2 (its initial state replaced
            // with nfa1's final state)
            nfa2.ShiftStates(nfa1.size - 1);

            // Creates a new NFA and initialize it with (the shifted) nfa2
            NFA newNFA = new NFA(nfa2);

            // nfa1's states take their places in newNFA
            // note: nfa1's final state overwrites nfa2's initial state,
            // thus we get the desired merge automagically (the transition
            // from nfa2's initial state now transits from nfa1's final state)
            newNFA.FillStates(nfa1);

            // Sets the new initial state (the final state stays nfa2's final state,
            // and was already copied)
            newNFA.initial = nfa1.initial;

            return(newNFA);
        }
Beispiel #3
0
        /// <summary>
        /// Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
        /// </summary>
        /// <param name="nfa1"></param>
        /// <param name="nfa2"></param>
        /// <returns></returns>
        public static NFA BuildNFAAlter(NFA nfa1, NFA nfa2)
        {
            // How this is done: the new nfa must contain all the states in
            // nfa1 and nfa2, plus a new initial and final states.
            // First will come the new initial state, then nfa1's states, then
            // nfa2's states, then the new final state

            // make room for the new initial state
            nfa1.ShiftStates(1);

            // make room for nfa1
            nfa2.ShiftStates(nfa1.size);

            // create a new nfa and initialize it with (the shifted) nfa2
            NFA newNFA = new NFA(nfa2);

            // nfa1's states take their places in new_nfa
            newNFA.FillStates(nfa1);

            // Set new initial state and the transitions from it
            newNFA.AddTrans(0, nfa1.initial, (char)Constants.Epsilon);
            newNFA.AddTrans(0, nfa2.initial, (char)Constants.Epsilon);

            newNFA.initial = 0;

            // Make up space for the new final state
            newNFA.AppendEmptyState();

            // Set new final state
            newNFA.final = newNFA.size - 1;

            newNFA.AddTrans(nfa1.final, newNFA.final, (char)Constants.Epsilon);
            newNFA.AddTrans(nfa2.final, newNFA.final, (char)Constants.Epsilon);

            return(newNFA);
        }