Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
                }
            }
        }