public static void TestRegExp() { a = new Regex("a"); b = new Regex("b"); // expr1: "baa" expr1 = new Regex("baa"); // expr2: "bb" expr2 = new Regex("bb"); // expr3: "baa | baa" expr3 = expr1.or(expr2); // all: "(a|b)*" all = (a.or(b)).star(); // expr4: "(baa | baa)+" expr4 = expr3.plus(); // expr5: "(baa | baa)+ (a|b)*" expr5 = expr4.dot(all); // converting to NDFA int i = 0; NDFA <int, char> ndfa = expr5.toNDFA(ref i); string ndfaTest = "baab"; tester(ndfaTest, ndfa.accept(ndfaTest.ToCharArray())); Console.WriteLine("-----NDFA Graph-----"); GraphViz.PrintNDFA(ndfa, "ndfa"); }
public NDFA <T, U> reverse(U epsilon) { NDFA <T, U> result = new NDFA <T, U>(epsilon); // Add DFA's startstate as endstate result.addEndState(StartState); foreach (T endState in EndStates) { result.addStartState(endState); } forEachTransition((terminal, fromState, toState) => result.addTransition(terminal, toState, fromState)); return(result); }
public static void PrintNDFA <T, U>(NDFA <T, U> ndfa, string filename) { var s = "digraph{ "; s += GetFinalStatesData(ndfa.EndStates); s += GetStartStatesData(ndfa.StartStates); s += "node [shape = circle];"; ndfa.forEachTransition((terminal, fromState, toState) => s += TransitionToString(terminal, fromState, toState)); s += " }"; Console.WriteLine(s); GenerateGraphFile(s, filename, Enums.GraphReturnType.Svg); }
public NDFA <int, char> toNDFA(ref int i) { NDFA <int, char> ndfaLeft = left?.toNDFA(ref i); NDFA <int, char> ndfaRight = right?.toNDFA(ref i); var ndfa = new NDFA <int, char>('$', ndfaLeft, ndfaRight); switch (op) { case Operator.ONE: var currState = ++i; ndfa.addStartState(currState); foreach (var terminal in terminals) { ndfa.addTransition(terminal, currState, currState = ++i); } ndfa.addEndState(currState); break; case Operator.OR: var orStartState = ++i; var orEndState = ++i; ndfa.addStartState(orStartState); ndfa.addTransition(ndfa.Epsilon, orStartState, ndfaLeft.StartStates.First()); ndfa.addTransition(ndfa.Epsilon, orStartState, ndfaRight.StartStates.First()); ndfa.addTransition(ndfa.Epsilon, ndfaLeft.EndStates.Last(), orEndState); ndfa.addTransition(ndfa.Epsilon, ndfaRight.EndStates.Last(), orEndState); ndfa.addEndState(orEndState); break; case Operator.DOT: ndfa.addStartState(ndfaLeft.StartStates.First()); ndfa.addEndState(ndfaRight.EndStates.Last()); ndfa.addTransition(ndfa.Epsilon, ndfaLeft.EndStates.Last(), ndfaRight.StartStates.First()); break; case Operator.PLUS: ndfa = plusAndStarOperatorHandlerCalledByToNDFA(ndfa, ndfaLeft, ref i); break; case Operator.STAR: ndfa = plusAndStarOperatorHandlerCalledByToNDFA(ndfa, ndfaLeft, ref i); break; default: break; } return(ndfa); }
private NDFA <int, char> plusAndStarOperatorHandlerCalledByToNDFA(NDFA <int, char> ndfa, NDFA <int, char> left, ref int i) { var startState = ++i; var endState = ++i; ndfa.addStartState(startState); ndfa.addEndState(endState); ndfa.addTransition(ndfa.Epsilon, startState, left.StartStates.First()); ndfa.addTransition(ndfa.Epsilon, left.EndStates.Last(), left.StartStates.First()); ndfa.addTransition(ndfa.Epsilon, left.EndStates.Last(), endState); if (op == Operator.STAR) { ndfa.addTransition(ndfa.Epsilon, startState, endState); } return(ndfa); }
public NDFA(U epsilon, NDFA <T, U> ndfa1, NDFA <T, U> ndfa2) { Epsilon = epsilon; if (ndfa1 != null) { Alphabet.UnionWith(ndfa1.Alphabet); } if (ndfa2 != null) { Alphabet.UnionWith(ndfa2.Alphabet); } Transitions = ndfa1 != null && ndfa2 != null ? ndfa1.Transitions.Concat(ndfa2.Transitions).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) : ndfa1 != null ? ndfa1.Transitions : ndfa2 != null ? ndfa2.Transitions : Transitions; }