Exemplo n.º 1
0
        private void ParseString(
            CommandTreeParserContext context,
            CommandTreeTokenStream stream,
            CommandTree node)
        {
            if (context.State == State.Remaining)
            {
                stream.Consume(CommandTreeToken.Kind.String);
                return;
            }

            var token = stream.Expect(CommandTreeToken.Kind.String);

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

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

                return;
            }

            // Current command has no arguments?
            if (!node.HasArguments())
            {
                throw ParseException.UnknownCommand(_configuration, node, context.Arguments, token);
            }

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

            if (parameter == null)
            {
                // No parameters left. Any commands after this?
                if (node.Command.Children.Count > 0 || node.Command.IsDefaultCommand)
                {
                    throw ParseException.UnknownCommand(_configuration, node, context.Arguments, token);
                }

                throw ParseException.CouldNotMatchArgument(context.Arguments, token);
            }

            // Yes, this was an argument.
            if (parameter.ParameterKind == ParameterKind.Vector)
            {
                // Vector
                var current = stream.Current;
                while (current?.TokenKind == CommandTreeToken.Kind.String)
                {
                    var value = stream.Consume(CommandTreeToken.Kind.String)?.Value;
                    node.Mapped.Add(new MappedCommandParameter(parameter, value));
                    current = stream.Current;
                }
            }
            else
            {
                // Scalar
                var value = stream.Consume(CommandTreeToken.Kind.String)?.Value;
                node.Mapped.Add(new MappedCommandParameter(parameter, value));
                context.IncreaseArgumentPosition();
            }
        }