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); }
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); }