Exemplo n.º 1
0
        private static RuleResult SpecificToken(
            Token t,
            TokenType type,
            string content,
            object node = null
            )
        {
            if (t.Type != type || t.Content != content)
            {
                string msg = $@"Expected the {type} ""{content}"", but got the {t.Type} ""{t.Content}"" instead.";
                return(RuleResult.Failed(t.Position, msg));
            }

            // If a node was provided, return a Completed result instead of GoodSoFar
            if (node != null)
            {
                return(RuleResult.Complete(node));
            }

            return(RuleResult.GoodSoFar());
        }
Exemplo n.º 2
0
        public RuleResult FeedToken(Token t)
        {
            if (!_isInitialized)
            {
                Initialize();
            }

            if (_isFinished)
            {
                throw new Exception("Tried to feed a token to an already-finished MultiRuleParser.");
            }

            if (_remainingRules.Count == 0)
            {
                throw new Exception("Tried to feed a token to an unfinished yet empty MultiRuleParser.");
            }

            // Feed the token to each rule
            var ruleResults = _remainingRules
                              .Select(r => (rule: r, result: r.FeedToken(t)))
                              .ToArray();

            // Eliminate all of the rules that failed
            foreach (var p in ruleResults)
            {
                if (p.result.status == RuleStatus.Failed)
                {
                    _remainingRules.Remove(p.rule);

                    // If that was the last subrule, then the whole
                    // ruleset fails.
                    if (_remainingRules.Count == 0)
                    {
                        return(p.result);
                    }
                }
            }

            // If one of the rules succeeds, crown it the winner.
            // Its result will be returned and its callback will be
            // invoked.
            // If more than one rule succeeds, the first rule added
            // to the list gets priority.
            var completedRules = ruleResults
                                 .Where(p => p.result.status == RuleStatus.Complete);

            if (completedRules.Any())
            {
                _isFinished = true;

                var winner = completedRules.First();
                var node   = winner.result.node;

                _ruleCallbacks[winner.rule](node);
                return(winner.result);
            }

            // None of them succeeded, but not all of them failed.
            // That's the definition of being "good so far".
            return(RuleResult.GoodSoFar());
        }