/// <summary> /// Translation from concatenation (dot) (rule 3) /// </summary> /// <param name="reg">the regular expression created with the RegExp class</param> /// <param name="automaton">the NDFA</param> /// <param name="stateCounter">keeps track of the next state to add</param> /// <param name="leftState">From state</param> /// <param name="rightState">To state</param> public static void Regel3(RegExp reg, List <Node> automaton, int stateCounter, int leftState, int rightState) { var newState = stateCounter + 1; stateCounter = newState; //node c, a dot means that there is atleast 1 new node automaton.Add(new Node(new List <Connection>(), "q" + newState, NodeType.NormalNode)); ModifyAutomaat(reg.left, automaton, stateCounter, leftState, newState); //handle left side of the dot ModifyAutomaat(reg.right, automaton, stateCounter, newState, rightState); //handle right side of the dot }
/// <summary> /// create a NDFA given a RegExp /// </summary> /// <param name="reg">the given RegExp</param> /// <returns> a list of nodes from which to create a NDFA</returns> public static List <Node> CreateAutomaat(RegExp reg) { List <Node> automaton = new List <Node>() //our list of nodes, initialized with a start and end node, they are a given for any automaton { new Node(new List <Connection>(), "q0", NodeType.StartNode), //node a new Node(new List <Connection>(), "q1", NodeType.EndNode) //node b }; //leftstate is initially the startnode, rightstate the endnode, statecounter keeps track of the last node in automaton int stateCounter = 1, leftState = 0, rightState = 1; ModifyAutomaat(reg, automaton, stateCounter, leftState, rightState); return(automaton); }
/// <summary> /// The translation of the plus operator (+) (rule 5) /// </summary> /// <param name="reg">the regular expression created with the RegExp class</param> /// <param name="automaton">the NDFA</param> /// <param name="stateCounter">keeps track of the next state to add</param> /// <param name="leftState">From state</param> /// <param name="rightState">To state</param> public static void Regel5(RegExp reg, List <Node> automaton, int stateCounter, int leftState, int rightState) { var newLeftState = stateCounter + 1; var newRightState = newLeftState + 1; stateCounter = newRightState; //add 2 new nodes for the + operator automaton.Add(new Node(new List <Connection>(), "q" + newLeftState, NodeType.NormalNode)); //node c automaton.Add(new Node(new List <Connection>(), "q" + newRightState, NodeType.NormalNode)); //node d automaton[leftState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from a to c automaton[newRightState].AddConnection(new Connection('ϵ', automaton[rightState])); //from d to b automaton[newRightState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from d to c ModifyAutomaat(reg.left, automaton, stateCounter, newLeftState, newRightState); //a plus operator has no right side }
/// <summary> /// The translation of the star operator (*) (rule 6) /// </summary> /// <param name="reg">the regular expression created with the RegExp class</param> /// <param name="automaton">the NDFA</param> /// <param name="stateCounter">keeps track of the next state to add</param> /// <param name="leftState">From state</param> /// <param name="rightState">To state</param> public static void Regel6(RegExp reg, List <Node> automaton, int stateCounter, int leftState, int rightState) { var newLeftState = stateCounter + 1; var newRightState = newLeftState + 1; stateCounter = newRightState; automaton.Add(new Node(new List <Connection>(), "q" + newLeftState, NodeType.NormalNode)); //node c automaton.Add(new Node(new List <Connection>(), "q" + newRightState, NodeType.NormalNode)); //node d automaton[leftState].AddConnection(new Connection('ϵ', automaton[rightState])); //from a to b automaton[leftState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from a to c automaton[newRightState].AddConnection(new Connection('ϵ', automaton[rightState])); //from d to b automaton[newRightState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from d to c //rule 6 has no right state (*) so we only need to check the left state ModifyAutomaat(reg.left, automaton, stateCounter, newLeftState, newRightState); }
/// <summary> /// The translation of the choice operator (or) (rule 4) /// </summary> /// <param name="reg">the regular expression created with the RegExp class</param> /// <param name="automaton">the NDFA</param> /// <param name="stateCounter">keeps track of the next state to add</param> /// <param name="leftState">From state</param> /// <param name="rightState">To state</param> public static void Regel4(RegExp reg, List <Node> automaton, int stateCounter, int leftState, int rightState) { //the first path to handle (left side) var newLeftState = stateCounter + 1; var newRightState = newLeftState + 1; stateCounter = newRightState; //node c, add a new node for the or left side(the first epsilon) automaton.Add(new Node(new List <Connection>(), "q" + newLeftState, NodeType.NormalNode)); //node d, the new node has a connection to automaton[rightState] with epsilon (the last epsilon) automaton.Add(new Node(new List <Connection>() { new Connection('ϵ', automaton[rightState]) }, "q" + newRightState, NodeType.NormalNode)); //from d to b automaton[leftState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from a to c ModifyAutomaat(reg.left, automaton, stateCounter, newLeftState, newRightState); //handle left side of the or //there are 2 paths to handle, this handles the second one (right side) newLeftState = stateCounter + 1; newRightState = newLeftState + 1; stateCounter = newRightState; //node e, add a new node for the or right side (the first epsilon) automaton.Add(new Node(new List <Connection>(), "q" + newLeftState, NodeType.NormalNode)); //node f, the new node has a connection to automaton[rightState] with epsilon (the last epsilon) automaton.Add(new Node(new List <Connection>() { new Connection('ϵ', automaton[rightState]) }, "q" + newRightState, NodeType.NormalNode)); //from f to b automaton[leftState].AddConnection(new Connection('ϵ', automaton[newLeftState])); //from a to e ModifyAutomaat(reg.right, automaton, stateCounter, newLeftState, newRightState); //handle right side of the or }
public void Regexparse(string s) { Console.WriteLine("entered string: " + s); RegexTester tester; try { tester = new RegexTester(s); } catch (Exception ex) { Console.WriteLine(ex.Message); return; } string answer = new String(s.Distinct().ToArray()); answer = new String(answer.Where(Char.IsLetter).ToArray()); List <string> strings = GenerateStrings.GenerateString(5, answer); RegExp exp = RegexParser.parse(s); List <Node> ndfa = Thompson.CreateAutomaat(exp); NDFA NDFAregularexpression = new NDFA(new List <Node>() { ndfa[0] }, ndfa); List <string> regexcorrect = tester.geefTaalTotN(5, answer); List <string> regexincorrect = tester.geefFoutieveTaalTotN(5, answer); CreateGraph(NDFAregularexpression.Nodes, "REGEX_NDFA"); DFA DFAregularexpression = NDFAtoDFA.ToDFA2(NDFAregularexpression); CreateGraph(DFAregularexpression.Nodes, "REGEX_DFA"); NDFA Reverse = DFAReverse.Reverse2(DFAregularexpression); CreateGraph(Reverse.Nodes, "REGEX_DFA_Reverse"); Console.WriteLine("-------- Correct words Contains --------"); foreach (String item in regexcorrect) { Console.WriteLine(item); } Console.WriteLine("-------- incorrect words --------"); foreach (String item in regexincorrect) { Console.WriteLine(item); } Console.WriteLine("-------- regex/ndfa/dfa/ndfa Reversed --------"); foreach (string item in strings) { Console.WriteLine(tester.Check(item)); Console.WriteLine(NDFAregularexpression.Check(item)); Console.WriteLine(DFAregularexpression.Check(item)); Console.WriteLine("reverse " + Reverse.Check(item)); } }
public void HardcodedExamples() { List <string> strings = GenerateStrings.GenerateString(5, "ab"); #region DFA //------------------------------- DFA ------------------------------- Console.WriteLine("---------- DFA -------------"); Console.WriteLine("------- hardcoded ----------"); Console.WriteLine("---- begins with babaa -----"); List <Node> DFA_BWB_ABAA_Nodes = new List <Node>() { new Node("q0", NodeType.StartNode), new Node("q1", NodeType.NormalNode), new Node("q2", NodeType.NormalNode), new Node("q3", NodeType.NormalNode), new Node("q4", NodeType.NormalNode), new Node("q5", NodeType.EndNode), new Node("q6", NodeType.NormalNode) }; DFA_BWB_ABAA_Nodes[0].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[1]), new Connection('a', DFA_BWB_ABAA_Nodes[6]) }); DFA_BWB_ABAA_Nodes[1].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[6]), new Connection('a', DFA_BWB_ABAA_Nodes[2]) }); DFA_BWB_ABAA_Nodes[2].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[3]), new Connection('a', DFA_BWB_ABAA_Nodes[6]) }); DFA_BWB_ABAA_Nodes[3].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[6]), new Connection('a', DFA_BWB_ABAA_Nodes[4]) }); DFA_BWB_ABAA_Nodes[4].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[6]), new Connection('a', DFA_BWB_ABAA_Nodes[5]) }); DFA_BWB_ABAA_Nodes[5].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[5]), new Connection('a', DFA_BWB_ABAA_Nodes[5]) }); DFA_BWB_ABAA_Nodes[6].AddConnections(new List <Connection>() { new Connection('b', DFA_BWB_ABAA_Nodes[6]), new Connection('a', DFA_BWB_ABAA_Nodes[6]) }); DFA BeginsWithBABAA = new DFA(DFA_BWB_ABAA_Nodes[0], DFA_BWB_ABAA_Nodes); foreach (string item in strings) { Console.WriteLine(BeginsWithBABAA.Check(item)); } CreateGraph(DFA_BWB_ABAA_Nodes, "DFA_BWBABAA"); Console.WriteLine("---- starts with abb or ends with baab -----"); List <Node> DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes = new List <Node>() { new Node("q0", NodeType.StartNode), new Node("q1", NodeType.NormalNode), new Node("q2", NodeType.NormalNode), new Node("q3", NodeType.EndNode), new Node("q4", NodeType.NormalNode), new Node("q5", NodeType.NormalNode), new Node("q6", NodeType.NormalNode), new Node("q7", NodeType.NormalNode), new Node("q8", NodeType.EndNode) }; DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[0].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[1]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[4]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[1].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[6]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[2]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[2].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[6]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[3]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[3].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[3]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[3]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[4].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[4]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[5]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[5].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[6]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[5]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[6].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[7]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[5]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[7].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[4]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[8]) }); DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[8].AddConnections(new List <Connection>() { new Connection('a', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[4]), new Connection('b', DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[5]) }); DFA StartsWithABBorEndsWithBAAB = new DFA(DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes[0], DFA_STARTW_ABB_OR_ENDSW_BAAB_Nodes); foreach (string item in strings) { Console.WriteLine(StartsWithABBorEndsWithBAAB.Check(item)); } CreateGraph(StartsWithABBorEndsWithBAAB.Nodes, "DFA_STARTWABBORENDSWBAAB"); #endregion #region HopCroft List <Node> HopCraftNodes = new List <Node>() { new Node("q0", NodeType.StartNode), new Node("q1", NodeType.NormalNode), new Node("q2", NodeType.EndNode), new Node("q3", NodeType.NormalNode), new Node("q4", NodeType.NormalNode) }; HopCraftNodes[0].AddConnections(new List <Connection>() { new Connection('a', HopCraftNodes[1]), new Connection('b', HopCraftNodes[2]) }); HopCraftNodes[1].AddConnections(new List <Connection>() { new Connection('a', HopCraftNodes[3]), new Connection('b', HopCraftNodes[0]) }); HopCraftNodes[2].AddConnections(new List <Connection>() { new Connection('a', HopCraftNodes[2]), new Connection('b', HopCraftNodes[4]) }); HopCraftNodes[3].AddConnections(new List <Connection>() { new Connection('a', HopCraftNodes[2]), new Connection('b', HopCraftNodes[1]) }); HopCraftNodes[4].AddConnections(new List <Connection>() { new Connection('a', HopCraftNodes[2]), new Connection('b', HopCraftNodes[1]) }); DFA HopCraft = new DFA(HopCraftNodes[0], HopCraftNodes); HopCraft = HopCroft.MinimizeHopCroft(HopCraft); CreateGraph(HopCraft.Nodes, "DFA_HopCroft"); #endregion #region NDFA //------------------------------- NDFA ------------------------------- Console.WriteLine("---------- NDFA ------------"); Console.WriteLine("---- Contains aa or bb -----"); List <Node> NDFA_C_AAoBB_Nodes = new List <Node>() { new Node("q0", NodeType.StartNode), new Node("q1", NodeType.NormalNode), new Node("q2", NodeType.NormalNode), new Node("q3", NodeType.EndNode), }; NDFA_C_AAoBB_Nodes[0].AddConnections(new List <Connection>() { new Connection('b', NDFA_C_AAoBB_Nodes[0]), new Connection('a', NDFA_C_AAoBB_Nodes[0]), new Connection('b', NDFA_C_AAoBB_Nodes[2]), new Connection('a', NDFA_C_AAoBB_Nodes[1]) }); NDFA_C_AAoBB_Nodes[1].AddConnections(new List <Connection>() { new Connection('a', NDFA_C_AAoBB_Nodes[3]), new Connection('b', NDFA_C_AAoBB_Nodes[0]) }); NDFA_C_AAoBB_Nodes[2].AddConnections(new List <Connection>() { new Connection('b', NDFA_C_AAoBB_Nodes[3]), new Connection('a', NDFA_C_AAoBB_Nodes[0]) }); NDFA_C_AAoBB_Nodes[3].AddConnections(new List <Connection>() { new Connection('b', NDFA_C_AAoBB_Nodes[3]), new Connection('a', NDFA_C_AAoBB_Nodes[3]) }); NDFA ContainsAAorBB = new NDFA(new List <Node>() { NDFA_C_AAoBB_Nodes[0] }, NDFA_C_AAoBB_Nodes); foreach (string item in strings) { Console.WriteLine(ContainsAAorBB.Check(item)); } CreateGraph(NDFA_C_AAoBB_Nodes, "NDFA_CAAoBB"); #endregion #region regex //---------------------------- regex ------------------------------- List <string> regexstrings = GenerateStrings.GenerateString(5, "abc"); Console.WriteLine("---------- regex ------------"); Console.WriteLine("--------- (a|bc)* ----------"); RegexTester regexTester = new RegexTester(@"(a|bc)*"); foreach (string item in regexstrings) { Console.WriteLine(regexTester.Check(item)); } Console.WriteLine("--------- wrong ----------"); List <string> foutievetaal = regexTester.geefFoutieveTaalTotN(5, "abc"); foreach (string item in foutievetaal) { Console.WriteLine(regexTester.Check(item)); } Console.WriteLine("--------- correct ----------"); List <string> correctetaal = regexTester.geefTaalTotN(5, "abc"); foreach (string item in correctetaal) { Console.WriteLine(regexTester.Check(item)); } #endregion #region GenerateBeginsWith Console.WriteLine("-------- Generated --------"); List <Node> BeginsWithBABAANodes = GenerateDFA.GenerateDFABeginsWith("babaa", "ab"); Node beginsstartnode = null; foreach (Node item in BeginsWithBABAANodes) { if (item.nodeType == NodeType.StartNode) { beginsstartnode = item; } } DFA GEN_BeginsWithBABAA = new DFA(beginsstartnode, BeginsWithBABAANodes); foreach (string item in strings) { Console.WriteLine(GEN_BeginsWithBABAA.Check(item)); } List <String> correctWordsbw = GEN_BeginsWithBABAA.geefTaalTotN(5, "ab"); Console.WriteLine("-------- Correct words BeginsWithBABAA --------"); foreach (String s in correctWordsbw) { Console.WriteLine(s); } List <String> inCorrectWordsbw = GEN_BeginsWithBABAA.geefFoutieveTaalTotN(5, "ab"); Console.WriteLine("-------- incorrect words BeginsWithBABAA --------"); foreach (String s in inCorrectWordsbw) { Console.WriteLine(s); } CreateGraph(GEN_BeginsWithBABAA.Nodes, "GEN_DFABWBABAA"); #endregion #region GenerateEndsWith List <Node> EndsWithBABAANodes = GenerateDFA.GenerateDFAEndsWith("aabab", "ab"); Node EndsWithstartnode = null; foreach (Node item in EndsWithBABAANodes) { if (item.nodeType == NodeType.StartNode) { EndsWithstartnode = item; } } DFA GEN_EndsWithBABAA = new DFA(EndsWithstartnode, EndsWithBABAANodes); foreach (string item in strings) { Console.WriteLine(GEN_EndsWithBABAA.Check(item)); } List <String> correctWordsew = GEN_EndsWithBABAA.geefTaalTotN(5, "ab"); Console.WriteLine("-------- Correct words EndsWithAABAB --------"); foreach (String s in correctWordsew) { Console.WriteLine(s); } List <String> inCorrectWordsew = GEN_EndsWithBABAA.geefFoutieveTaalTotN(5, "ab"); Console.WriteLine("-------- incorrect words EndsWithAABAB --------"); foreach (String s in inCorrectWordsew) { Console.WriteLine(s); } CreateGraph(GEN_EndsWithBABAA.Nodes, "GEN_DFAEWAABAB"); #endregion #region Contains List <Node> ContainsBABAANodes = GenerateDFA.GenerateDFAContains("bab", "ab"); Node Containsstartnode = null; foreach (Node item in ContainsBABAANodes) { if (item.nodeType == NodeType.StartNode) { Containsstartnode = item; } } DFA GEN_ContainsBABAA = new DFA(Containsstartnode, ContainsBABAANodes); foreach (string item in strings) { Console.WriteLine(GEN_ContainsBABAA.Check(item)); } List <String> correctWordsc = GEN_ContainsBABAA.geefTaalTotN(5, "ab"); Console.WriteLine("-------- Correct words ContainsBAB --------"); foreach (String s in correctWordsc) { Console.WriteLine(s); } List <String> inCorrectWordsc = GEN_ContainsBABAA.geefFoutieveTaalTotN(5, "ab"); Console.WriteLine("-------- incorrect words ContainsBAB --------"); foreach (String s in inCorrectWordsc) { Console.WriteLine(s); } CreateGraph(GEN_ContainsBABAA.Nodes, "GEN_DFAEWBAB"); #endregion #region Regex -> NDFA Console.WriteLine("---------- Regular expression tester with Regex and Thompson ------------"); Console.WriteLine("---------- (a|bc)* -----------"); regexTester = new RegexTester(@"(a|bc)*"); RegExp reg = new RegExp("a").or(new RegExp("b").dot(new RegExp("c"))).star(); List <Node> ndfa = Thompson.CreateAutomaat(reg); NDFA NDFAregularexpression2 = new NDFA(new List <Node>() { ndfa[0] }, ndfa); foreach (string item in strings) { Console.WriteLine(NDFAregularexpression2.Check(item)); Console.WriteLine("Regex test: " + regexTester.Check(item)); } CreateGraph(NDFAregularexpression2.Nodes, "NDFA_RegexThompsonToNDFA"); #endregion #region NDFAtoDFA //--------------------------- NDFA -> DFA --------------------------- Console.WriteLine("---- test NDFA to DFA -----"); Console.WriteLine("---------- NDFA -----------"); List <Node> NDFATODFA = new List <Node>() { new Node("q1", NodeType.StartNode), new Node("q2", NodeType.EndNode), new Node("q3", NodeType.EndNode), new Node("q4", NodeType.NormalNode), new Node("q5", NodeType.NormalNode) }; NDFATODFA[0].AddConnections(new List <Connection>() { new Connection('b', NDFATODFA[1]), new Connection('a', NDFATODFA[1]), new Connection('b', NDFATODFA[2]), }); NDFATODFA[1].AddConnections(new List <Connection>() { new Connection('a', NDFATODFA[2]), new Connection('ϵ', NDFATODFA[3]), new Connection('b', NDFATODFA[3]) }); NDFATODFA[2].AddConnections(new List <Connection>() { new Connection('a', NDFATODFA[1]) }); NDFATODFA[3].AddConnections(new List <Connection>() { new Connection('a', NDFATODFA[4]), new Connection('a', NDFATODFA[1]) }); NDFATODFA[4].AddConnections(new List <Connection>() { new Connection('b', NDFATODFA[4]), new Connection('ϵ', NDFATODFA[2]) }); NDFA TESTNDFATODFA = new NDFA(new List <Node>() { NDFATODFA[0] }, NDFATODFA); CreateGraph(TESTNDFATODFA.Nodes, "NDFA_NDFAtoDFA"); foreach (string item in strings) { //Console.WriteLine(TESTNDFATODFA.Check(item)); } Console.WriteLine("----------- DFA -----------"); DFA TESTDFA = NDFAtoDFA.ToDFA2(TESTNDFATODFA); CreateGraph(TESTDFA.Nodes, "DFA_NDFAtoDFA"); foreach (string item in strings) { Console.WriteLine(TESTNDFATODFA.Check(item)); Console.WriteLine(TESTDFA.Check(item)); } #endregion #region Reverse Console.WriteLine("---- (NDFA) reverse begins with babaa -----"); NDFA reversedBABAA = DFAReverse.Reverse2(BeginsWithBABAA); foreach (string item in strings) { Console.WriteLine(reversedBABAA.Check(item)); } CreateGraph(reversedBABAA.Nodes, "ReversedBABAA"); #endregion }
/// <summary> /// A basic parser that rewrites strings into a RegExp object. /// </summary> /// <param name="text">The text to create a RegExp from</param> /// <returns>a RegExp based on the text</returns> public static RegExp parse(string text) { RegExp regex = new RegExp(); //the output RegExp object Mode currentMode = 0; //no dot or or found yet List <Char> chars = new List <char>(); //memory of all found characters, needed for ) and or //parse each letter foreach (char c in text.ToCharArray()) { //What does the letter mean for the conversion? switch (c) { case '(': //can be ignored break; case ')': //handle all leftover characters since we are going up in depth RegExp reg = new RegExp(); foreach (Char ch in chars) { if (reg.left == null && reg.right == null && reg.terminals == "") { reg = new RegExp(ch.ToString()); //if it's the first charachter } else { reg = reg.dot(new RegExp(ch.ToString())); //there was atleast 1 character before this one } } chars.Clear(); //chars are used, array can be cleard regex = regex.or(reg); currentMode = 0; //or used to set mode back to nothing break; case '|': //or detected currentMode = Mode.or; break; case '+': //+ detected regex = regex.plus(); break; case '*': //star detected regex = regex.star(); break; case '.': //dot detected currentMode = Mode.dot; break; default: //no special character detected switch (currentMode) //the mode is important for handling the dot, or and one { case Mode.nothing: if (regex.left == null && regex.right == null && regex.terminals == "") { regex = new RegExp(c.ToString()); //if it's the first charachter } else { regex = regex.dot(new RegExp(c.ToString())); //there was atleast 1 character before this one } break; case Mode.or: chars.Add(c); //an or expects all characters in one RegExp object, add them to an array first break; case Mode.dot: regex = regex.dot(new RegExp(c.ToString())); break; } break; } } if (chars.Count != 0) //makes sure a Regexp object is properly closed off. { RegExp reg = new RegExp(); foreach (Char ch in chars) { if (reg.left == null && reg.right == null && reg.terminals == "") { reg = new RegExp(ch.ToString()); //if it's the first charachter } else { reg = reg.dot(new RegExp(ch.ToString())); //there was atleast 1 character before this one } } regex = regex.or(reg); } return(regex); }