Exemplo n.º 1
0
        public void addRangeTransitionsToDFA(
            Dictionary <RangeTransition <T>, int> dfaTransitions,
            Dictionary <int, RegexTrie <T> > allDTries,
            RegexTrie <T> origin)
        {
            foreach (var trans in dfaTransitions)
            {
                if (!allDTries.ContainsKey(trans.Value))
                {
                    allDTries[trans.Value] = new RegexTrie <T>();
                }
                RegexTrie <T> target = allDTries[trans.Value];

                origin.AddRangeTransition(
                    target, trans.Key.rangeStart, trans.Key.rangeEnd, trans.Key.groupNumber);
            }
        }
        //Add transitions from a square bracket group between the tries given as arguments.
        //Returns the amount of characters consumed from the input string (so the string index can be incremented).
        private int handleSquareBracketGroup(RegexTrie <T> sourceTrie, RegexTrie <T> targetTrie, string sourceTail)
        {
            Boolean isEscaped    = false;
            Boolean isComplement = false;
            //The complement transition to build
            ComplementTransition <T> complement = new ComplementTransition <T>(0, targetTrie);

            //Check whether this is a complement set
            if (sourceTail[0] == '^')
            {
                //Add complement transition to trie
                sourceTrie.complementTransitions.Add(complement);

                isComplement = true;
                sourceTail   = sourceTail.Substring(1);
            }

            StringBuilder set = new StringBuilder();
            char          currentChar;

            //First build a string out of the expression, then add every char in it or its complement to the trie
            //as transitions
            for (int stringIndex = 0; stringIndex < sourceTail.Length; stringIndex++)
            {
                currentChar = sourceTail[stringIndex];

                if (isEscaped)
                {
                    set       = handleEscaped(set, currentChar);
                    isEscaped = false;
                    continue;
                }

                switch (currentChar)
                {
                case '\\':
                {
                    isEscaped = true;
                    break;
                }

                case '-':
                {
                    char start = sourceTail[stringIndex - 1];
                    char end   = sourceTail[stringIndex + 1];
                    //Add a range transition, which can be a complement
                    if (isComplement)
                    {
                        complement.ranges.Add(new KeyValuePair <char, char>(start, end));
                    }
                    else
                    {
                        sourceTrie.AddRangeTransition(
                            targetTrie,
                            start,
                            end,
                            0);
                    }
                    //Remove the range start from set
                    set.Remove(set.Length - 1, 1);

                    //skip the range end
                    stringIndex++;
                    break;
                }

                //Add the set or its complement as transitions
                case ']':
                {
                    string finalSet = set.ToString();
                    if (isComplement)
                    {
                        complement.characters.AddRange(finalSet);
                        //One character was consumed by the complement special character, so increment by 2
                        return(stringIndex + 2);
                    }
                    else
                    {
                        foreach (char c in finalSet)
                        {
                            sourceTrie.AddCharacterTransition(c, 0, targetTrie);
                        }
                        return(stringIndex + 1);
                    }
                }

                default:
                {
                    set.Append(currentChar);
                    break;
                }
                }
            }
            //This should never be reached, as the regex is validated to always contain closing square bracket
            return(-1);
        }