Ejemplo n.º 1
0
        /// <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);
        }