/// <summary> /// If a matcher in the sequence doesn't match, then it doesn't match /// </summary> /// <param name="context"></param> /// <param name="start"></param> /// <returns></returns> public override MatchResult Matches(MatchContext context, TokenEntity startToken, PatternMatcher nextPatternMatcher) { var tokenEntity = startToken; int start = startToken?.Start ?? 0; int end = 0; int minMatches = 1; int maxMatches = this.MaxMatches; switch (Ordinality) { case Ordinality.One: maxMatches = 1; break; case Ordinality.OneOrMore: break; case Ordinality.ZeroOrMore: minMatches = 0; break; case Ordinality.ZeroOrOne: minMatches = 0; maxMatches = 1; break; } int matched = 0; MatchResult matchResult = null; bool found; do { found = false; for (int iPattern = 0; iPattern < PatternMatchers.Count; iPattern++) { var patternMatcher = PatternMatchers[iPattern]; var result = patternMatcher.Matches(context, tokenEntity, nextPatternMatcher); if (result.Matched) { found = true; matched++; matchResult = result; end = Math.Max(result.End, end); tokenEntity = matchResult.NextToken; if (matched == maxMatches) { // then we are done; return(new MatchResult(true, this, tokenEntity, start, end) { NextPatternMatch = result.NextPatternMatch }); } break; } else { if (matchResult != null) { matchResult.NextPatternMatch = result.NextPatternMatch; } } } } while (found && tokenEntity != null); if (matched < minMatches) { // not matched. return(new MatchResult(false, this) { NextPatternMatch = matchResult?.NextPatternMatch }); } return(new MatchResult(true, this, tokenEntity, start, end) { NextPatternMatch = matchResult?.NextPatternMatch }); }
public override MatchResult Matches(MatchContext context, TokenEntity startToken, PatternMatcher nextPatternMatcher) { var tokenEntity = startToken; if (tokenEntity != null) { if (nextPatternMatcher != null) { MatchResult nextPatternMatch = nextPatternMatcher?.Matches(context, tokenEntity, null); if (nextPatternMatch.Matched && nextPatternMatch.NextToken != tokenEntity) { return(new MatchResult(false, this) { NextPatternMatch = nextPatternMatch }); } } if (!context.IsTokenMatched(tokenEntity)) { // if last child is a wildcard and it's end matches the last token's end // then we will merge the wildcards together. var previousToken = context.GetPrevTokenEntity(tokenEntity); var wildcardEntity = context.CurrentEntity.Children.FirstOrDefault(wildcard => wildcard.Type == this.entityType && wildcard.End == previousToken.End); if (wildcardEntity != null) { var newEntity = new LucyEntity() { Type = entityType, Start = wildcardEntity.Start, End = tokenEntity.End, Score = ((float)tokenEntity.End - wildcardEntity.Start) / context.Text.Length / 2, Text = context.Text.Substring(wildcardEntity.Start, tokenEntity.End - wildcardEntity.Start), Resolution = context.Text.Substring(wildcardEntity.Start, tokenEntity.End - wildcardEntity.Start), }; // remove old entity context.CurrentEntity.Children.Remove(wildcardEntity); // add new merged wildcard entity "joe" "smith" => "joe smith" context.AddToCurrentEntity(newEntity); } else { var newEntity = new LucyEntity() { Type = entityType, Start = tokenEntity.Start, End = tokenEntity.End, Score = ((float)tokenEntity.End - tokenEntity.Start) / context.Text.Length / 2, Text = context.Text.Substring(tokenEntity.Start, tokenEntity.End - tokenEntity.Start), Resolution = context.Text.Substring(tokenEntity.Start, tokenEntity.End - tokenEntity.Start) }; context.AddToCurrentEntity(newEntity); } return(new MatchResult(true, this, context.GetNextTokenEntity(tokenEntity), tokenEntity.Start, tokenEntity.End)); } } return(new MatchResult(false, this)); }