public static NFA Or(NFA a, NFA b)
        {
            NFA nfa = new NFA();

            // Composite NFA contains all the and all edges in both NFAs
            nfa.AddAll(a);
            nfa.AddAll(b);

            // Add a start state, link to both NFAs old start state with
            // epsilon links
            nfa.StartState = new NFA.State();
            nfa.States.Add(nfa.StartState);

            nfa.Transitions.Add(new Transition <NFA.State>(nfa.StartState, a.StartState));
            nfa.Transitions.Add(new Transition <NFA.State>(nfa.StartState, b.StartState));

            // Add a new accept state, link all old accept states to the new accept
            // state with an epsilon link and remove the accept flag
            NFA.State newAcceptState = new NFA.State {
                AcceptState = true
            };

            foreach (NFA.State oldAcceptState in nfa.States.Where(f => f.AcceptState))
            {
                oldAcceptState.AcceptState = false;
                nfa.Transitions.Add(new Transition <NFA.State>(oldAcceptState, newAcceptState));
            }

            nfa.States.Add(newAcceptState);

            return(nfa);
        }
        public static NFA RepeatZeroOrMore(NFA input)
        {
            NFA nfa = new NFA();

            // Add everything from the input
            nfa.AddAll(input);
            // Create a new starting state, link it to the old accept state with Epsilon
            nfa.StartState = new NFA.State();
            nfa.States.Add(nfa.StartState);

            NFA.State oldAcceptState = input.States.First(f => f.AcceptState);

            nfa.Transitions.Add(new Transition <NFA.State>(nfa.StartState, oldAcceptState));
            // Add epsilon link from old accept state of input to start, to allow for repetition
            nfa.Transitions.Add(new Transition <NFA.State>(oldAcceptState, input.StartState));

            // Create new accept state, link old accept state to new accept state with epsilon
            NFA.State acceptState = new NFA.State {
                AcceptState = true
            };

            nfa.States.Add(acceptState);
            oldAcceptState.AcceptState = false;
            nfa.Transitions.Add(new Transition <NFA.State>(oldAcceptState, acceptState));

            return(nfa);
        }
        public static NFA And(NFA first, NFA second)
        {
            // Create a new NFA and use the first NFAs start state as the starting point
            NFA nfa = new NFA {
                StartState = first.StartState
            };

            // Change all links in to first acceptstate to go to seconds
            // start state
            foreach (Transition <NFA.State> edge in first.Transitions.Where(f => f.To.AcceptState))
            {
                edge.To = second.StartState;
            }

            // Remove acceptstate from first
            first.States.Remove(first.States.First(f => f.AcceptState));

            // Add all states and edges in both NFAs
            // Second NFA already has an accept state, there is no need to create another one
            nfa.AddAll(first);
            nfa.AddAll(second);

            return(nfa);
        }
Beispiel #4
0
        public static NFA Merge(IList <NFA> nfas)
        {
            // Create a new NFA, add everything to it.
            NFA merged = new NFA();

            foreach (NFA nfa in nfas)
            {
                merged.AddAll(nfa);
            }

            // Add a new start state
            State state = new State();

            merged.States.Add(state);
            merged.StartState = state;

            // Add epsilon transiontions from the start state to all the previous start states
            foreach (NFA nfa in nfas)
            {
                merged.Transitions.Add(new Transition <State>(state, nfa.StartState));
            }

            return(merged);
        }