/// <summary> /// Parses the source code searching for the longest matching term text from the specified terms. /// It returns the index of the longest matching term or -1, if there is no matching term at the specified source position. /// </summary> /// <param name="source">The source of an extension.</param> /// <param name="textSelector">The selector of term text at the specified 0 based index.</param> /// <param name="accept">if set to <c>true</c> accepts the position after parsed longest text.</param> /// <param name="charComparer">The character comparer.</param> /// <param name="termsCount">The number of terms.</param> /// <returns>The index of the longest matching text or -1, if there is no matching text at the specified source position.</returns> public static int ParseLongestMatchingString(this IParsingContextStream source, int termsCount, Func <int, string> textSelector, bool accept = false, IEqualityComparer <char> charComparer = null) { var text = Enumerable.Range(0, termsCount).Select(textSelector).ToArray(); var matchedTermIdx = -1; using (var ctx = source.GetFurtherContext()) { //go through all character indexes from 0 to longest matching term // for each term check if character at specified position matches // if char matches and it is last character, temporary accept position and exclude term by setting to null // if char doesn't match -> exclude term by setting to null // if there are no more matching terms -> break // if accept true and matchedTermIdx > -1 -> accept // return matchedTermIndex var charPosition = -1; while (ctx.MoveNext()) { charPosition++; var current = ctx.Current; var matchingTermsCount = 0; for (var termIdx = 0; termIdx < text.Length; termIdx++) { var currentTerm = text[termIdx]; if (currentTerm != null) { if (currentTerm.Length <= charPosition) { text[termIdx] = null; } if (Equals(currentTerm[charPosition], current, charComparer)) { if (currentTerm.Length == charPosition + 1) { matchedTermIdx = termIdx; ctx.Accept(); text[termIdx] = null; } else { matchingTermsCount++; } } else { text[termIdx] = null; } } } if (matchingTermsCount <= 0) { break; } } } if (accept && matchedTermIdx >= 0) { source.Accept(); } return(matchedTermIdx); }