private static NFA Accept(CharSet acceptCharacters) { // Generate a NFA with a simple path with one state transitioning into an accept state. var nfa = new NFA(); var state = new NFA.State(); nfa.States.Add(state); var acceptState = new NFA.State { AcceptState = true }; nfa.States.Add(acceptState); nfa.Transitions.Add(new Transition<NFA.State>(state, acceptState, acceptCharacters)); nfa.StartState = state; return nfa; }
private static NFA RepeatOnceOrMore(NFA nfa) { // Add an epsilon transition from the accept state back to the start state NFA.State oldAcceptState = nfa.States.First(f => f.AcceptState); nfa.Transitions.Add(new Transition<NFA.State>(oldAcceptState, nfa.StartState)); // Add a new accept state, since we cannot have edges exiting the accept state var newAcceptState = new NFA.State { AcceptState = true }; nfa.Transitions.Add(new Transition<NFA.State>(oldAcceptState, newAcceptState)); nfa.States.Add(newAcceptState); // Clear the accept flag of the old accept state oldAcceptState.AcceptState = false; return nfa; }
public static NFA RepeatZeroOrMore(NFA input) { var 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 var 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 Or(NFA a, NFA b) { var 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 var newAcceptState = new NFA.State { AcceptState = true }; foreach (var 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; }