public Match ( string text, int startIndex ) : |
||
text | string | |
startIndex | int | |
return |
public MatchResult Match(string text, int startIndex)
{
if(string.IsNullOrEmpty(text))
throw new ArgumentNullException(text);
var lastMatch = new MatchResult {Text = text};
int textLength = text.Length;
for (int currentIndex = startIndex; currentIndex < textLength; currentIndex ++)
{
//call any prefixless patternmatchers
#region HasExpressions
if (root.FirstExpression != null)
{
//begin with the first expression of the _root node_
PatternMatchReference patternMatcherReference = root.FirstExpression;
while (patternMatcherReference != null)
{
int patternMatchIndex = patternMatcherReference.Matcher.Match(text, currentIndex);
if (patternMatchIndex > 0 && patternMatchIndex > lastMatch.Length)
{
bool leftIsSeparator = currentIndex == 0 ? true : separatorCharLookup[text[currentIndex - 1]];
bool rightIsSeparator = (currentIndex+patternMatchIndex) == textLength ? true : separatorCharLookup[text[currentIndex + patternMatchIndex]];
if (!patternMatcherReference.NeedSeparators || (leftIsSeparator && rightIsSeparator))
{
lastMatch.Index = currentIndex;
lastMatch.Length = patternMatchIndex;
lastMatch.Found = true;
lastMatch.Tags = patternMatcherReference.Tags;
}
}
patternMatcherReference = patternMatcherReference.NextSibling;
}
}
#endregion
//lookup the first token tree node
TokenTreeNode node = nodes[text[currentIndex]];
if (node == null)
{
if (lastMatch.Found)
break;
continue;
}
for (int matchIndex = currentIndex + 1; matchIndex <= textLength; matchIndex++)
{
//call patternmatchers for the current prefix
#region HasExpressions
if (node.FirstExpression != null)
{
//begin with the first expression of the _current node_
PatternMatchReference patternMatcherReference = node.FirstExpression;
while (patternMatcherReference != null)
{
int patternMatchIndex = patternMatcherReference.Matcher.Match(text, matchIndex);
if (patternMatchIndex > 0 && patternMatchIndex > lastMatch.Length)
{
bool leftIsSeparator = currentIndex == 0 ? true : separatorCharLookup[text[currentIndex - 1]];
bool rightIsSeparator = (currentIndex+patternMatchIndex+matchIndex) == textLength ? true : separatorCharLookup[text[currentIndex + patternMatchIndex+matchIndex]];
if (!patternMatcherReference.NeedSeparators || (leftIsSeparator && rightIsSeparator))
{
lastMatch.Index = currentIndex;
lastMatch.Length = patternMatchIndex + matchIndex - currentIndex;
lastMatch.Found = true;
lastMatch.Tags = patternMatcherReference.Tags;
}
}
patternMatcherReference = patternMatcherReference.NextSibling;
}
}
#endregion
#region IsEndNode
if (node.IsEnd && matchIndex - currentIndex >= lastMatch.Length)
{
bool leftIsSeparator = currentIndex == 0 ? true : separatorCharLookup[text[currentIndex - 1]];
bool rightIsSeparator = matchIndex == textLength ? true : separatorCharLookup[text[matchIndex]];
if (!node.NeedSeparators || (leftIsSeparator && rightIsSeparator))
{
lastMatch.Index = currentIndex;
lastMatch.Tags = node.Tags;
lastMatch.Found = true;
lastMatch.Length = matchIndex - currentIndex;
//TODO:perform case test here , case sensitive words might be matched even if they have incorrect case
if (currentIndex + lastMatch.Length == textLength)
break;
}
}
#endregion
//try fetch a node at this index
node = node.GetNextNode(textLookup[text[matchIndex]]);
//we found no node on the lookupindex or none of the siblingnodes at that index matched the current char
if (node == null)
break; // continue with the next character
}
//return last match
if (lastMatch.Found)
return lastMatch;
}
if (lastMatch.Found)
return lastMatch;
//no match was found
return MatchResult.NoMatch;
}
}
public Token[] Tokenize() { if (Text == null) { throw new ArgumentNullException("Text"); } MakeImmutable(); var tokens = new List <Token>(); int index = 0; while (index < Text.Length) { MatchResult match = tree.Match(Text, index); if (match.Found) { string dummyText = Text.Substring(index, match.Index - index); var dummyToken = new Token(dummyText, null); tokens.Add(dummyToken); var realToken = new Token(match.GetText(), match.Tags); index = match.Index + match.Length; tokens.Add(realToken); } else { string dummyText = Text.Substring(index); var dummyToken = new Token(dummyText, null); tokens.Add(dummyToken); index = Text.Length; } } return(tokens.ToArray()); }