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()); }
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()); }