Esempio n. 1
0
        static CommandLine()
        {
            using (StringReader stringReader = new StringReader(Environment.CommandLine))
            using (BasicReader reader = new BasicReader(stringReader, StringComparer.Ordinal, disposeReader: false))
            {
                // just in case
                reader.AdvanceWhitespace();
                char first;
                if (reader.TryPeek(out first))
                {
                    if (first == '"')
                    {
                        reader.Skip(1);
                        Path = reader.ReadUntil(c => c == '"');
                        reader.Skip(1);
                    }
                    else
                        Path = reader.ReadUntil(char.IsWhiteSpace);

                    // skip whitespace
                    if (!reader.Eof)
                        reader.Skip(1);

                    // dirty hack to read to eof
                    Arguments = reader.ReadUntil(c => false);
                }
            }
        }
        protected virtual void ParseValue(TokenWriter tokenWriter, BasicReader reader)
        {
            int startPos = reader.Position;
            if (reader.StartsWith(ListValueSeperator))
            {
                tokenWriter.Add(new Token(TokenType.ListValueSeperator, ListValueSeperator, startPos, ListValueSeperator.Length));
                reader.Skip(1);
            }
            else if (reader.StartsWith("'") || reader.StartsWith("\""))
            {
                this.ParseQuotedString(tokenWriter, reader);
            }
            else if (reader.StartsWith("$"))
            {
                TokenType type;
                char[] endChar = new char[] {' ', '\t', '\r', '\n', ',', '}', ')', '=', ';' };

                string val = reader.ReadUntil(endChar.Contains);
                switch (val)
                {
                    case "$null":
                        type = TokenType.NullValue;
                        break;
                    case "$true":
                    case "$false":
                        type = TokenType.BoolValue;
                        break;
                    default:
                        throw new InvalidDataException("Not a literal token: " + val);
                }

                tokenWriter.Add(new Token(type, val, startPos, reader.Position - startPos));

            }
            else if (reader.StartsWith(DictionaryStart))
            {
                this.ParseDictionary(tokenWriter, reader);
            }
            else if (reader.StartsWith(ListStart))
            {
                this.ParseList(tokenWriter, reader);
            }
            else
            {
                char[] endChar = new char[] { ' ', '\t', '\r', '\n', ',', '}', ')', '=', ';' };
                string val = reader.PeekUntil(endChar.Contains);

                bool decimalSep = val.Any(c => c == '.');

                int skipSign = val[0] == '+' || val[0] == '-' ? 1 : 0;

                if (val.Skip(skipSign).Count(char.IsDigit) + (decimalSep ? 1 : 0) == val.Length - skipSign)
                {
                    reader.Skip(val.Length);
                    
                    tokenWriter.Add(new Token(TokenType.NumericValue, val, startPos, reader.Position - startPos));

                }
                else
                    this.ParseUnquotedString(tokenWriter, reader);
            }


        }
        protected virtual void ParseUnquotedString(TokenWriter tokenWriter, BasicReader reader)
        {
            // record position for later
            int pos = reader.Position;

            StringBuilder val = new StringBuilder();

            // escape char + stop chars
            char[] stopChars = new[] { '`', ' ', '\t', '\r', '\n', '}', ')', '=' };

            do
            {
                string tmp = reader.ReadUntil(stopChars.Contains);
                val.Append(tmp);

                char chr;
                if (reader.TryPeek(out chr))
                {
                    if (chr == '`')
                    {
                        // escape char, so skip one
                        reader.Read();

                        // then process the next
                        val.Append(reader.Read());
                    }
                    else
                    {
                        break; // exit
                    }
                }
            }
            while (!reader.Eof);

            tokenWriter.Add(new Token(TokenType.StringValue, val.ToString(), pos, reader.Position - pos));
        }
        protected virtual void ParseQuotedString(TokenWriter tokenWriter, BasicReader reader)
        {
            // record position for later
            int pos = reader.Position;

            // skip leading quote
            char quoteChar = reader.Read();

            StringBuilder val = new StringBuilder();

            // escape char + quote char
            char[] stopChars = new[] { '`', quoteChar };

            do
            {
                string tmp = reader.ReadUntil(stopChars.Contains);
                val.Append(tmp);

                char chr;
                if (reader.TryPeek(out chr))
                {
                    if (chr == '`')
                    {
                        // escape char, so skip one
                        reader.Read();

                        // then process the next
                        val.Append(reader.Read());
                    }
                    else if (chr == quoteChar)
                    {
                        break; // exit
                    }
                }
                else
                {
                    throw new Exception("Premature end of stream");
                }
            }
            while (!reader.Eof);

            // skip trailing quote
            reader.Skip(1);

            tokenWriter.Add(new Token(TokenType.StringValue, val.ToString(), pos, reader.Position - pos));
        }