private static IEnumerable <RuleMatch> GetMatches( IRule rule, ExplorerContext context) { var leftMatches = context.InvokeRule(rule); foreach (var m in leftMatches) { var newContext = context.MoveForward(m); var interleaveLength = newContext.MatchInterleave(); var fullMatch = m.AddInterleaveLength(interleaveLength); yield return(fullMatch); } }
public IEnumerable <RuleMatch> InvokeRule(IRule rule) { if (rule == null) { throw new ArgumentNullException(nameof(rule)); } if (Depth <= 1) { throw new ParsingException("Recursion exceeds limits"); } var newAmbiantRuleProperties = _ambiantRuleProperties.Merge(rule); var newExcepts = GetNewRuleExceptions(newAmbiantRuleProperties, rule); if (newExcepts != null) { var interleaveLength = _isInterleaveMatched ? 0 : MatchInterleave(); var newText = Text.Skip(interleaveLength); var newContext = new ExplorerContext( newText, _interleaveRule, true, Depth - 1, newExcepts, newAmbiantRuleProperties); var ruleMatches = rule.Match(newContext); var uniqueRuleMatchesWithInterleaves = new UniqueRuleMatchEnumerable(ruleMatches) .Select(m => m.AddInterleaveLength(interleaveLength)); #if DEBUG // Useful when debugging and faster than a breakpoint condition //if (rule.RuleName == "outputDeclaration") //{ //} // No yield, easier to debug var ruleMatchList = uniqueRuleMatchesWithInterleaves.ToArray(); return(ruleMatchList); #else return(uniqueRuleMatchesWithInterleaves); #endif } else { return(EMPTY_RULE_MATCHES); } }
public RuleMatch Match(string?ruleName, SubString text, int?depth = null) { if (string.IsNullOrWhiteSpace(ruleName)) { ruleName = DEFAULT_RULE_NAME; } if (!_ruleMap.ContainsKey(ruleName)) { throw new ParsingException($"Unknown rule to match: '{ruleName}'"); } var rule = _ruleMap[ruleName]; var context = new ExplorerContext(text, _interleaveRule, depth); var matches = GetMatches(rule, context); var exactLengthMatches = from m in matches where m.LengthWithInterleaves == text.Length select m; // Take the first available match (of right length) var match = exactLengthMatches.FirstOrDefault(); return(match); }
private int MatchInterleave(ExplorerContext interleaveContext) { if (_interleaveRule == null) { return(0); } else { var interleaveMatch = _interleaveRule.Match(interleaveContext).FirstOrDefault(); if (interleaveMatch == null || interleaveMatch.Text.Length == 0) { return(0); } else { var newInterleaveContext = interleaveContext.MoveForward(interleaveMatch); // Recursion var remainingLength = MatchInterleave(newInterleaveContext); return(interleaveMatch.Text.Length + remainingLength); } } }