internal override void BuildResult(Scanner s, out MatchResult result, Match m) { this.NewMatchResult(out result); this.m_pattern.BuildMatchResult(m, s.Reader.PosCurrent, s.PosWindowStart, ref result); SetPositionsInResult(ref result); return; }
private void Match(Scanner s, int idxPosition, Regex r, ref MatchResult result) { int idxMatchAt = idxPosition; if (this.LeadingContext > 0) { idxMatchAt -= this.LeadingContext; // SHOULD: idxMatchAt = Math.Min(idxMatchAt, s.GetIdxLineStartFor(s.m_idxMatchHead)); idxMatchAt = Math.Max(0, idxMatchAt); } Match m = r.Match(s.InputWindow.Window, idxMatchAt - s.PosWindowStart); if (m.Success) { this.BuildMatchResult(m, idxMatchAt, s.PosWindowStart, ref result); } else { result.Success = false; } }
internal void Match(Scanner s, int idxPosition, string[] externalCaptures, ref MatchResult result) { if (null == externalCaptures || externalCaptures.Length == 0) { this.Match(s, idxPosition, this.CachedRegex, ref result); return; } StringBuilder regexBuilder = new StringBuilder(this.RawRegex); int idxLastUsableCapture = Math.Min(externalCaptures.Length, this.LastExternalMatch); for (int i = 1; i <= idxLastUsableCapture; i++) { regexBuilder.Replace(StringExtensions.Fi("\\z{0}", i), externalCaptures[i - 1]); } Regex r = this.InstantiateRegex(regexBuilder.ToString(), false); this.Match(s, idxPosition, r, ref result); }
internal void Match(Scanner s, int idxPosition, ref MatchResult result) { if (0 < this.LastExternalMatch) { string msg = StringExtensions.Fi("Invalid call to Match(): no external captures were passed, but Pattern '{0}' expects them", this); throw new InvalidOperationException(msg); } this.Match(s, idxPosition, this.CachedRegex, ref result); }
private bool TryFindEndWithinLine(Scanner s, int posStartAt, string[] externalCaptures) { MatchResult result = new MatchResult(); int position = posStartAt; while (position <= s.PosWindowEnd) { result.MatchType = MatchType.RegionSkip; for (int i = 0; i < this.m_skipPatterns.Count; i++) { this.m_skipPatterns[i].Match(s, position, externalCaptures, ref result); if (result.Success) { while (position < result.PosAfterMatch) { position++; if ('\n' == s.InputWindow[position]) { return false; } } break; } } for (int i = 0; i < this.m_endPatterns.Count; i++) { this.m_endPatterns[i].Match(s, position, externalCaptures, ref result); if (result.Success) { return true; } } if ('\n' == s.InputWindow[position]) { return false; } position++; } return false; }
internal bool TrySkips(Scanner s, Scope scope, int posMatchAt) { if (posMatchAt <= scope.PosEndSkippedUntil || scope.PosAfter != int.MaxValue) { return false; } MatchResult result = new MatchResult(); result.MatchType = MatchType.RegionSkip; for (int i = 0; i < this.m_skipPatterns.Count; i++) { this.m_skipPatterns[i].Match(s, posMatchAt, scope.ExternalCaptures, ref result); if (result.Success) { if (result.PosAfterMatch <= s.PosWindowEnd) { if ('\n' == s[result.PosAfterMatch]) { result.PosAfterMatch++; } } scope.PosEndSkippedUntil = result.PosAfterMatch - 1; return true; } } return false; }
internal override MatchResult TryMatch(Scanner s) { MatchResult result; this.NewMatchResult(out result); for (int i = 0; i < this.m_startPatterns.Count; i++) { Pattern p = this.m_startPatterns[i]; p.Match(s, s.Reader.PosCurrent, ref result); if (!result.Success) { continue; } result.Pattern = p; if (this.IsOneLine) { bool foundEndWithinLine = TryFindEndWithinLine(s, result.PosAfterMatch, result.ExternalCaptures); if (!foundEndWithinLine) { // MAY: so we found a region start and then didn't find the end in the current line, and are now giving up on the region. // IN THEORY, we could try to keep matching other START patterns because we could for example have a different start pattern // that is, say, shorter, and for which the region end would match in this line. In practice, this works. break; } } return result; } result.Success = false; return result; }
internal bool TryEnding(Scanner s, Scope scope) { int posMatchAt = s.Reader.PosCurrent; if (posMatchAt <= scope.PosEndSkippedUntil || scope.PosAfter != int.MaxValue) { return false; } if (this.TrySkips(s, scope, posMatchAt)) { return false; } MatchResult result = new MatchResult(); result.MatchType = MatchType.RegionEnd; for (int i = 0; i < this.m_endPatterns.Count; i++) { this.m_endPatterns[i].Match(s, posMatchAt, scope.ExternalCaptures, ref result); if (result.Success) { scope.PosAfter = result.PosAfterMatch; bool hasHighlightMode = this.m_endPatterns[i].HasHighlightMode; if (0 == result.PosAfterRegion && hasHighlightMode) { result.PosAfterRegion = result.PosMatchStart; } if (0 == result.PosAfterHighlight) { result.PosAfterHighlight = result.PosAfterMatch; } if (hasHighlightMode && result.PosAfterRegion < result.PosAfterHighlight) { s.SendMode(this.m_endPatterns[i].HighlightMode, result.PosAfterRegion); } if (result.PosAfterHighlight < result.PosAfterMatch) { s.BuildHighlightModes(result.PosAfterHighlight); } return true; } } return false; }
internal override void StartScopeForSuccesfulMatch(Scanner s, MatchResult match) { Scope newScope = this.BuildNewScope(s.TopScope); newScope.PosMatchedAt = match.PosMatchedAt; newScope.ExternalCaptures = match.ExternalCaptures; bool hasHighlightMode = match.Pattern.HasHighlightMode; if (0 == match.PosRegionStart) { match.PosRegionStart = hasHighlightMode ? match.PosAfterMatch : match.PosMatchStart; } if (0 == match.PosHighlightStart) { match.PosHighlightStart = match.PosMatchStart; } if (hasHighlightMode && match.PosHighlightStart < match.PosRegionStart) { s.SendMode(match.Pattern.HighlightMode, match.PosHighlightStart); } newScope.PosStart = hasHighlightMode ? match.PosRegionStart : match.PosMatchStart; newScope.PosHighlightStart = hasHighlightMode ? match.PosRegionStart : match.PosHighlightStart; newScope.PosEndSkippedUntil = hasHighlightMode ? match.PosRegionStart - 1 : match.PosAfterMatch - 1; newScope.EatNewLineInRegion = match.Pattern.EatNewLine; s.PushScope(newScope); }
internal override void BuildResult(Scanner s, out MatchResult result, Match m) { if (this.IsOneLine) { result = this.TryMatch(s); return; } this.NewMatchResult(out result); for (int i = 0; i < this.m_startPatterns.Count; i++) { if (m.Groups["s" + i].Success) { result.Pattern = this.m_startPatterns[i]; this.m_startPatterns[i].BuildMatchResult(m, s.Reader.PosCurrent, s.PosWindowStart, ref result); return; } } string msg = StringExtensions.Fi("Unable to find pattern that matched for region '{0}'", this); throw new AssertionViolationException(msg); }
internal abstract void BuildResult(Scanner s, out MatchResult result, Match m);
internal abstract MatchResult TryMatch(Scanner s);
internal abstract void StartScopeForSuccesfulMatch(Scanner s, MatchResult match);
internal override void StartScopeForSuccesfulMatch(Scanner s, MatchResult match) { Scope newScope = this.BuildNewScope(match, s.TopScope); s.PushScope(newScope); return; }
internal override MatchResult TryMatch(Scanner s) { MatchResult result; this.NewMatchResult(out result); this.Pattern.Match(s, s.Reader.PosCurrent, ref result); SetPositionsInResult(ref result); return result; }