Ejemplo n.º 1
0
        private static Argument ParsePositionalArg(IEnumerator <Token> tokenIterator)
        {
            ArgumentDef def = GetNextPositionalDef();
            Argument    arg = new Argument();

            arg.Definition = def;


            sbyte iter = 0;

            List <object> argValues = new List <object>();

            do
            {
                iter++;
                Token token = tokenIterator.Current;

                if (token.Type != TokenType.BareArg)
                {
                    return(arg);
                }

                argValues.Add(ConvertTokenDataToType(token.Data, def.DataType));
            } while ((def.Consumption < 0 || (iter < def.Consumption)) && tokenIterator.MoveNext());

            if (argValues.Count < def.Consumption)
            {
                throw new Exception(string.Format(
                                        "Not enough values for positional argument '{0}'; {1} {2} required.",
                                        def.ToString(),
                                        def.Consumption,
                                        def.Consumption > 1 ? "are" : "is"
                                        ));
            }

            if (def.Consumption == 1)
            {
                arg.Value = argValues[0];
            }
            else
            {
                arg.Value = argValues;
            }

            return(arg);
        }
Ejemplo n.º 2
0
        private static Argument ParseShortArg(IEnumerator <Token> tokenIterator)
        {
            Token token = tokenIterator.Current;

            ArgumentDef def = GetDefByToken(token);

            Argument arg = new Argument();

            arg.Definition = def;

            if (def.Consumption == 0)               // No consumption
            {
                return(arg);
            }
            else if (def.Consumption == 1)               // Consume single following argument
            {
                if (tokenIterator.MoveNext())
                {
                    Token  next = tokenIterator.Current;
                    string data;

                    // If the next token is a ShortOption but we're a consumer, grab new bare data out of the
                    // next sequential ShortOptions
                    switch (next.Type)
                    {
                    case TokenType.ShortOption:
                        data = ConsumeSequentialShortOptions(tokenIterator);
                        break;

                    case TokenType.BareArg:
                        data = (string)next.Data;
                        break;

                    default:
                        throw new Exception(string.Format(
                                                "Unexpected token type '{0}' after '{1}': Expected one of '{2}'",
                                                next.Type,
                                                token.Type,
                                                Utils.JoinArray(new TokenType[] {
                            TokenType.BareArg
                        })
                                                ));
                    }

                    arg.Value = ConvertTokenDataToType(data, def.DataType);
                    return(arg);
                }

                throw new Exception(string.Format(
                                        "No arguments after option '{0}'; {1} {2} required.",
                                        def.ToString(),
                                        def.Consumption,
                                        def.Consumption > 1 ? "are" : "is"
                                        ));
            }
            else if (def.Consumption < 0)               // Greedy
            {
                bool          firstTime = true;
                List <object> argData   = new List <object>();

                while (tokenIterator.MoveNext())
                {
                    Token  next = tokenIterator.Current;
                    string tokenData;

                    switch (next.Type)
                    {
                    case TokenType.ShortOption:
                        if (firstTime)
                        {
                            tokenData = ConsumeSequentialShortOptions(tokenIterator);
                        }
                        else
                        {
                            arg.Value = argData;
                            return(arg);
                        }
                        break;

                    case TokenType.BareArg:
                        tokenData = (string)next.Data;
                        break;

                    default:
                        if (firstTime)
                        {
                            throw new Exception(string.Format(
                                                    "Unexpected token type '{0}' after '{1}': Expected one of '{2}'",
                                                    next.Type,
                                                    token.Type,
                                                    Utils.JoinArray(new TokenType[] {
                                TokenType.ShortOption,
                                TokenType.BareArg
                            })
                                                    ));
                        }
                        else
                        {
                            arg.Value = argData;
                            return(arg);
                        }
                    }

                    argData.Add(ConvertTokenDataToType(tokenData, def.DataType));
                }

                if (argData.Count < 1)
                {
                    throw new Exception(string.Format(
                                            "No arguments after greedy option '{0}'; at least one is required.",
                                            def.ToString()
                                            ));
                }
                arg.Value = argData;
                return(arg);
            }
            else               // Fixed, positive number of args.
            {
                bool          firstTime = true;
                List <object> argData   = new List <object>();

                sbyte iter = 0;
                while (iter++ < def.Consumption && tokenIterator.MoveNext())
                {
                    Token  next = tokenIterator.Current;
                    string tokenData;

                    switch (next.Type)
                    {
                    case TokenType.ShortOption:
                        if (firstTime)
                        {
                            tokenData = ConsumeSequentialShortOptions(tokenIterator);
                        }
                        else
                        {
                            arg.Value = argData;
                            return(arg);
                        }
                        break;

                    case TokenType.BareArg:
                        tokenData = (string)next.Data;
                        break;

                    default:
                        if (firstTime)
                        {
                            throw new Exception(string.Format(
                                                    "Unexpected token type '{0}' after '{1}': Expected one of '{2}'",
                                                    next.Type,
                                                    token.Type,
                                                    Utils.JoinArray(new TokenType[] {
                                TokenType.ShortOption,
                                TokenType.BareArg
                            })
                                                    ));
                        }
                        else
                        {
                            if (argData.Count < def.Consumption)
                            {
                                throw new Exception(string.Format(
                                                        "Not enough arguments after option '{0}'; {1} {2} required.",
                                                        def.ToString(),
                                                        def.Consumption,
                                                        def.Consumption > 1 ? "are" : "is"
                                                        ));
                            }

                            arg.Value = argData;
                            return(arg);
                        }
                    }

                    argData.Add(ConvertTokenDataToType(tokenData, def.DataType));
                }

                if (argData.Count < def.Consumption)
                {
                    throw new Exception(string.Format(
                                            "Not enough arguments after option '{0}'; {1} {2} required.",
                                            def.ToString(),
                                            def.Consumption,
                                            def.Consumption > 1 ? "are" : "is"
                                            ));
                }

                arg.Value = argData;
                return(arg);
            }
        }
Ejemplo n.º 3
0
        public static ArgumentDef AddArgument(
            char shortName,
            string longName,
            Type dataType            = default(Type),
            ArgumentType argType     = ArgumentType.Positional,
            ArgumentStatus argStatus = ArgumentStatus.Required,
            sbyte consumption        = 0
            )
        {
            ArgumentDef def = new ArgumentDef(shortName, longName, dataType, argType, argStatus, consumption);

            int _;

            if (def.ShortName != ArgumentDef.nullChar && defsByShort.TryGetValue(def.ShortName, out _))
            {
                throw new Exception(string.Format("Cannot add new argument with duplicate short name '{0}'", def.ShortName));
            }

            if (def.LongName != ArgumentDef.emptyString && defsByLong.TryGetValue(def.LongName, out _))
            {
                throw new Exception(string.Format("Cannot add new argument with duplicate long name \"{0}\"", def.LongName));
            }

            if (def.ArgType == ArgumentType.Positional && def.ArgStatus == ArgumentStatus.Required && optionalPositionalDefined)
            {
                throw new Exception("Cannot add new required positional arguments after optional positional arguments.");
            }

            if (def.ArgType == ArgumentType.Positional && def.ArgStatus == ArgumentStatus.Required && greedyArgDefined)
            {
                throw new Exception("Cannot add new required positional arguments after greedy arguments.");
            }

            defs.Add(def);

            if (def.Consumption < 0)
            {
                greedyArgDefined = true;
            }

            if (def.ArgType == ArgumentType.Positional)
            {
                positionalDefs.Add(def);

                if (def.ArgStatus == ArgumentStatus.Optional)
                {
                    optionalPositionalDefined = true;
                }
            }

            if (def.ArgStatus == ArgumentStatus.Required)
            {
                requiredDefs.Add(def);
            }

            if (def.ShortName != ArgumentDef.nullChar)
            {
                defsByShort[def.ShortName] = defs.Count - 1;
            }

            if (def.LongName != ArgumentDef.emptyString)
            {
                defsByLong[def.LongName] = defs.Count - 1;
            }

            return(def);
        }