Пример #1
0
        public override void Parse(StringReader reader, CommandContextBuilder <TSource> contextBuilder)
        {
            var start = reader.Cursor;
            var end   = Parse(reader);

            if (end > -1)
            {
                contextBuilder.WithNode(this, StringRange.Between(start, end));
                return;
            }

            throw CommandSyntaxException.BuiltInExceptions.LiteralIncorrect().CreateWithContext(reader, Literal);
        }
Пример #2
0
        private ParseResults <TSource> ParseNodes(CommandNode <TSource> node, StringReader originalReader, CommandContextBuilder <TSource> contextSoFar)
        {
            var source = contextSoFar.Source;
            IDictionary <CommandNode <TSource>, CommandSyntaxException> errors = null;
            List <ParseResults <TSource> > potentials = null;
            var cursor = originalReader.Cursor;

            foreach (var child in node.GetRelevantNodes(originalReader))
            {
                if (!child.CanUse(source))
                {
                    continue;
                }

                var context = contextSoFar.Copy();
                var reader  = new StringReader(originalReader);
                try
                {
                    try
                    {
                        child.Parse(reader, context);
                    }
                    catch (CommandSyntaxException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw CommandSyntaxException.BuiltInExceptions.DispatcherParseException().CreateWithContext(reader, ex.Message);
                    }

                    if (reader.CanRead())
                    {
                        if (reader.Peek() != ArgumentSeparatorChar)
                        {
                            throw CommandSyntaxException.BuiltInExceptions.DispatcherExpectedArgumentSeparator().CreateWithContext(reader);
                        }
                    }
                }
                catch (CommandSyntaxException ex)
                {
                    if (errors == null)
                    {
                        errors = new Dictionary <CommandNode <TSource>, CommandSyntaxException>();
                    }

                    errors.Add(child, ex);
                    reader.Cursor = cursor;
                    continue;
                }

                context.WithCommand(child.Command);
                if (reader.CanRead(child.Redirect == null ? 2 : 1))
                {
                    reader.Skip();
                    if (child.Redirect != null)
                    {
                        var childContext = new CommandContextBuilder <TSource>(this, source, child.Redirect, reader.Cursor);
                        var parse        = ParseNodes(child.Redirect, reader, childContext);
                        context.WithChild(parse.Context);
                        return(new ParseResults <TSource>(context, parse.Reader, parse.Exceptions));
                    }
                    else
                    {
                        var parse = ParseNodes(child, reader, context);
                        if (potentials == null)
                        {
                            potentials = new List <ParseResults <TSource> >(1);
                        }

                        potentials.Add(parse);
                    }
                }
                else
                {
                    if (potentials == null)
                    {
                        potentials = new List <ParseResults <TSource> >(1);
                    }

                    potentials.Add(new ParseResults <TSource>(context, reader, new Dictionary <CommandNode <TSource>, CommandSyntaxException>()));
                }
            }

            if (potentials != null)
            {
                if (potentials.Count > 1)
                {
                    potentials.Sort((a, b) =>
                    {
                        if (!a.Reader.CanRead() && b.Reader.CanRead())
                        {
                            return(-1);
                        }

                        if (a.Reader.CanRead() && !b.Reader.CanRead())
                        {
                            return(1);
                        }

                        if (a.Exceptions.Count == 0 && b.Exceptions.Count > 0)
                        {
                            return(-1);
                        }

                        if (a.Exceptions.Count > 0 && b.Exceptions.Count == 0)
                        {
                            return(1);
                        }

                        return(0);
                    });
                }

                return(potentials[0]);
            }

            return(new ParseResults <TSource>(contextSoFar, originalReader, errors ?? new Dictionary <CommandNode <TSource>, CommandSyntaxException>()));
        }
Пример #3
0
        /**
         * Parses a given command.
         *
         * <p>The result of this method can be cached, and it is advised to do so where appropriate. Parsing is often the
         * most expensive step, and this allows you to essentially "precompile" a command if it will be ran often.</p>
         *
         * <p>If the command passes through a node that is {@link CommandNode#isFork()} then the resulting context will be marked as 'forked'.
         * Forked contexts may contain child contexts, which may be modified by the {@link RedirectModifier} attached to the fork.</p>
         *
         * <p>Parsing a command can never fail, you will always be provided with a new {@link ParseResults}.
         * However, that does not mean that it will always parse into a valid command. You should inspect the returned results
         * to check for validity. If its {@link ParseResults#getReader()} {@link StringReader#canRead()} then it did not finish
         * parsing successfully. You can use that position as an indicator to the user where the command stopped being valid.
         * You may inspect {@link ParseResults#getExceptions()} if you know the parse failed, as it will explain why it could
         * not find any valid commands. It may contain multiple exceptions, one for each "potential node" that it could have visited,
         * explaining why it did not go down that node.</p>
         *
         * <p>When you eventually call {@link #execute(ParseResults)} with the result of this method, the above error checking
         * will occur. You only need to inspect it yourself if you wish to handle that yourself.</p>
         *
         * @param command a command string to parse
         * @param source a custom "source" object, usually representing the originator of this command
         * @return the result of parsing this command
         * @see #parse(String, Object)
         * @see #execute(ParseResults)
         * @see #execute(String, Object)
         */
        public ParseResults <TSource> Parse(StringReader command, TSource source)
        {
            var context = new CommandContextBuilder <TSource>(this, source, _root, command.Cursor);

            return(ParseNodes(_root, command, context));
        }
Пример #4
0
 public override void Parse(StringReader reader, CommandContextBuilder <TSource> contextBuilder)
 {
 }
Пример #5
0
        public ArgumentCommandNodeTest()
        {
            _node = RequiredArgumentBuilder <object, int> .RequiredArgument("foo", Arguments.Integer()).Build();

            _contextBuilder = new CommandContextBuilder <object>(new CommandDispatcher <object>(), new object(), new RootCommandNode <object>(), 0);
        }
Пример #6
0
 public CommandContextTest()
 {
     _builder = new CommandContextBuilder <object>(_dispatcher, _source, _rootNode, 0);
 }
Пример #7
0
        public LiteralCommandNodeTest()
        {
            _node = LiteralArgumentBuilder <object> .LiteralArgument("foo").Build();

            _contextBuilder = new CommandContextBuilder <object>(new CommandDispatcher <object>(), new object(), new RootCommandNode <object>(), 0);
        }
Пример #8
0
 /// <exception cref="CommandSyntaxException"></exception>
 public abstract void Parse(StringReader reader, CommandContextBuilder <TSource> contextBuilder);
Пример #9
0
 public ParseResults(CommandContextBuilder <TSource> context, IImmutableStringReader reader, IDictionary <CommandNode <TSource>, CommandSyntaxException> exceptions)
 {
     Context    = context;
     Reader     = reader;
     Exceptions = exceptions;
 }
Пример #10
0
 public ParseResults(CommandContextBuilder <TSource> context)
     : this(context, new StringReader(""), new Dictionary <CommandNode <TSource>, CommandSyntaxException>())
 {
 }