public bool Equals(ComplementTransition <T> x, ComplementTransition <T> y) { foreach (char c in x.characters) { if (!y.characters.Contains(c)) { return(false); } } foreach (KeyValuePair <char, char> kv in x.ranges) { Boolean identicalRangeFound = false; foreach (KeyValuePair <char, char> kv2 in y.ranges) { if ((kv.Key == kv2.Key) && (kv.Value == kv2.Value)) { identicalRangeFound = true; } } if (!identicalRangeFound) { return(false); } } return(x.groupNumber == y.groupNumber); }
public int GetHashCode(ComplementTransition <T> trans) { int hashCode = 0; foreach (char c in trans.characters) { hashCode = c.GetHashCode() ^ hashCode; } foreach (KeyValuePair <char, char> kv in trans.ranges) { hashCode = kv.Value.GetHashCode() ^ kv.Key.GetHashCode() ^ hashCode; } return(trans.groupNumber.GetHashCode() ^ hashCode); }
//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); }