예제 #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 CommandParseException.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 CommandParseException.UnknownCommand(_configuration, node, context.Arguments, token);
            }

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