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); }