public IEnumerable <ICommand> Parse(string statement) { if (statement == null) { throw new ArgumentException(""); } IRule command = null; IRule current = null; List <IArgumentRule> options = new List <IArgumentRule>(); var tokens = statement.Tokenize(); var commandWord = tokens.ElementAt(0); if (!_syntax.ContainsWord(commandWord)) { throw new ArgumentException(commandWord); } command = _syntax.FindRule(commandWord); current = command; options.AddRange(command.OptionalArgs); if (!IsEnoughArguments(current, commandWord, tokens)) { throw new ArgumentNotEnoughException(commandWord); } yield return(new Command(commandWord, action: command.Action)); foreach (var word in tokens.Skip(1)) { if (current.RequiredArgs.ContainsWord(word)) { current = current.RequiredArgs.FindRule(word); options.AddRange(current.OptionalArgs); if (!IsEnoughArguments(current, word, tokens)) { throw new ArgumentNotEnoughException(word); } yield return(new Command(word, action: current.Action)); continue; } var wordSplited = word.SplitIntoKeyValue(); var option = options.FindRule(wordSplited.Key); if (!option.IsNullOrEmpty()) { if (!IsEnoughArguments(current, word, tokens)) { throw new ArgumentNotEnoughException(current.Name); } yield return(new Command(wordSplited.Key, wordSplited.Value, option.Action)); continue; } throw new ArgumentException(word); } }
private IEnumerable <ICandidate> GetArgumentCandidates(string command, IEnumerable <string> args) { Contract.Ensures(Contract.Result <IEnumerable <ICandidate> >() != null); if (args.Count() == 0) { return(Empty); } var rule = _syntax.FindRule(command); var currentWord = args.Last(); var currentRules = rule.FindApplyingRules(args); var lastRule = currentRules.Last(); if (currentWord.IsOption()) { var options = currentRules.Where(x => x.OptionalArgs != null).SelectMany(x => x.OptionalArgs); if (currentWord.HasOptionValue()) { var keyValue = currentWord.SplitIntoKeyValue(); return(options.FindRule(keyValue.Key).OptionalArgs.GetCandidates(keyValue.Value)); } return(options.GetCandidates(currentWord)); } return(lastRule.RequiredArgs.GetCandidates(currentWord)); }