Ejemplo n.º 1
0
        public (CommandTree tree, ILookup <string, string> remaining) Parse(IEnumerable <string> args)
        {
            var tokens  = Tokenizer.Tokenize(args);
            var context = new CommandTreeParserContext();

            var result = (CommandTree)null;

            if (tokens.Count > 0)
            {
                var token = tokens.Current;
                if (token.TokenType != Token.Type.String)
                {
                    if (_help != null)
                    {
                        if (_help.ShortName?.Equals(token.Value, StringComparison.Ordinal) == true ||
                            _help.LongName?.Equals(token.Value, StringComparison.Ordinal) == true)
                        {
                            // Show help
                            return(null, context.GetRemainingArguments());
                        }
                    }
                    throw new CommandAppException($"Unexpected option '{token.Value}'.");
                }
                result = ParseCommand(context, _configuration, null, tokens);
            }

            return(result, context.GetRemainingArguments());
        }
Ejemplo n.º 2
0
        private void ParseString(
            CommandTreeParserContext context,
            TokenStream stream,
            CommandTree node)
        {
            var token = stream.Expect(Token.Type.String);

            // Command?
            var command = node.Command.FindCommand(token.Value);

            if (command != null)
            {
                node.Next = ParseCommand(context, node.Command, node, stream);
                return;
            }

            // Current command has no arguments?
            if (!node.HasArguments())
            {
                throw new CommandAppException($"Unknown child command '{token.Value}' of '{node.Command.Name}'.");
            }

            // Argument?
            var parameter = node.FindArgument(context.CurrentArgumentPosition);

            if (parameter == null)
            {
                throw new CommandAppException($"Could not match '{token.Value}' with an argument.");
            }

            node.Mapped.Add((parameter, stream.Consume(Token.Type.String).Value));

            context.IncreaseArgumentPosition();
        }
Ejemplo n.º 3
0
        private CommandTree ParseCommand(
            CommandTreeParserContext context,
            ICommandContainer current,
            CommandTree parent,
            TokenStream stream)
        {
            context.ResetArgumentPosition();

            // Find the command.
            var commandToken = stream.Consume(Token.Type.String);
            var command      = current.FindCommand(commandToken.Value);

            if (command == null)
            {
                throw new CommandAppException($"Unknown command '{commandToken.Value}'.");
            }

            var node = new CommandTree(parent, command);

            while (stream.Peek() != null)
            {
                var token = stream.Peek();
                switch (token.TokenType)
                {
                case Token.Type.LongOption:
                    // Long option
                    ParseOption(context, stream, node, true);
                    break;

                case Token.Type.ShortOption:
                    // Short option
                    ParseOption(context, stream, node, false);
                    break;

                case Token.Type.String:
                    // Command
                    ParseString(context, stream, node);
                    break;

                default:
                    throw new InvalidOperationException("Unknown token type.");
                }
            }

            // Add unmapped parameters.
            foreach (var parameter in node.Command.Parameters)
            {
                if (node.Mapped.All(m => m.Item1 != parameter))
                {
                    node.Unmapped.Add(parameter);
                }
            }

            return(node);
        }
Ejemplo n.º 4
0
        private void ParseOption(
            CommandTreeParserContext context,
            TokenStream stream,
            CommandTree node,
            bool isLongOption)
        {
            // Get the option token.
            var token = stream.Consume(isLongOption ? Token.Type.LongOption : Token.Type.ShortOption);

            // Find the option.
            var option = node.FindOption(token.Value, isLongOption);

            if (option != null)
            {
                node.Mapped.Add((option, ParseParameterValue(stream, node, option)));
                return;
            }

            // Help?
            if (_help != null)
            {
                if (_help.ShortName?.Equals(token.Value, StringComparison.Ordinal) == true ||
                    _help.LongName?.Equals(token.Value, StringComparison.Ordinal) == true)
                {
                    node.ShowHelp = true;
                    return;
                }
            }

            // Parent does not have this option mapped?
            if (!node.IsMappedWithParent(token.Value, isLongOption))
            {
                // Add this option as an remaining argument.
                var optionName = token.TokenType == Token.Type.LongOption ? $"--{token.Value}" : $"-{token.Value}";
                context.AddRemainingArgument(optionName, ParseParameterValue(stream, node, null));
            }
        }