/// <summary> /// Parses the regex and converts it into an NFA. /// </summary> /// <param name="regex"></param> private NFA RegexToNFA(string regex, ref int index) { bool bracket = false; if (index >= 0 && index < regex.Length) { bracket = (regex[index] == '('); } if (bracket || (index < 0)) { index++; } NFA result = null; while (index < regex.Length && regex[index] != ')') { NFA newNFA = null; int combineMode = -1; //0 = concat, 1 = alternate switch (regex[index]) { case '(': newNFA = RegexToNFA(regex, ref index); combineMode = 0; break; case '|': index++; newNFA = RegexToNFA(regex, ref index); combineMode = 1; break; case '*': index++; combineMode = -1; break; case '[': byte[] transitionBytes = GetTransitionSet(regex, ref index); newNFA = NFA.ByteTransitionNFA(transitionBytes); combineMode = 0; break; case '.': transitionBytes = new byte[256]; for (int b = byte.MinValue; b <= byte.MaxValue; b++) { transitionBytes[b] = (byte)b; } newNFA = NFA.ByteTransitionNFA(transitionBytes); combineMode = 0; index++; break; case ']': throw new ParseException("Error at position " + index + "! No ']' expected. Escape it!"); case '\\': index++; transitionBytes = new byte[] { Convert.ToByte(regex[index++]) }; newNFA = NFA.ByteTransitionNFA(transitionBytes); combineMode = 0; break; default: transitionBytes = new byte[] { Convert.ToByte(regex[index++]) }; newNFA = NFA.ByteTransitionNFA(transitionBytes); combineMode = 0; break; } if (index < regex.Length && regex[index] == '*') { newNFA.KleeneStar(); index++; } if (combineMode == 0) { result = NFA.ConcatNFAs(result, newNFA); } else if (combineMode == 1) { result = NFA.AlternateNFAs(result, newNFA); } } if (bracket && (index < regex.Length) && regex[index] == ')') { index++; } else if (bracket && ((index >= regex.Length) || regex[index] != ')')) { throw new ParseException("Error at position " + index + "! Closing bracket expected!"); } return(result); }