示例#1
0
        private static bool ParseWord(StringStream stream, ICollection <Token> tokens)
        {
            if (char.IsLetter(stream.Peek()) || stream.Peek() == '_')
            {
                string word = "";

                while (!stream.IsEndOfStream && (char.IsLetterOrDigit(stream.Peek()) || stream.Peek() == '_'))
                {
                    word += stream.Read();
                }

                switch (word)
                {
                case "true":
                    tokens.Add(new Token(TokenType.Number, "1", Filename, Line));
                    break;

                case "false":
                    tokens.Add(new Token(TokenType.Number, "0", Filename, Line));
                    break;

                default:
                    tokens.Add(new Token(TokenType.Word, word, Filename, Line));
                    break;
                }

                return(true);
            }

            return(false);
        }
示例#2
0
        private static bool ParseString(StringStream stream, ICollection <Token> tokens)
        {
            if (!(stream.Peek() == '@' && stream.Peek(1) == '\"') && stream.Peek() != '\"')
            {
                return(false);
            }

            uint   startLine = Line;
            string value     = "";

            bool escaped = true;

            if (stream.Peek() == '@')
            {
                escaped = false;
                stream.Read();
            }

            while (stream.Peek() == '\"')
            {
                char ch;

                ++stream.Position;
                while ((ch = stream.Read()) != '\"')
                {
                    if (stream.IsEndOfStream)
                    {
                        throw new LexerException("Unterminated string on line {0}.", startLine);
                    }

                    if (ch == StringStream.NewLine)
                    {
                        ++Line;
                    }

                    value += ch;
                    if (ch == '\\')
                    {
                        value += stream.Read();
                    }
                }

                SkipWhitespace(stream);
            }

            value = escaped ? ParseEscapeSequence(value) : value;
            tokens.Add(new Token(TokenType.String, value, Filename, startLine));

            return(true);
        }
示例#3
0
        private static bool SkipComment(StringStream stream)
        {
            // Skip single line comments
            if (stream.Peek() == '/' && stream.Peek(1) == '/')
            {
                while (!stream.IsEndOfStream && stream.Peek() != StringStream.NewLine)
                {
                    stream.Read();
                }

                return(true);
            }

            // Skip multiline comments
            if (stream.Peek() == '/' && stream.Peek(1) == '*')
            {
                stream.Position += 2;
                int nestCount = 1;

                while (nestCount > 0)
                {
                    if (stream.IsEndOfStream)
                    {
                        throw new LexerException("Unterminated multi-line comment ran past end of file.");
                    }

                    if (stream.Peek() == '/' && stream.Peek(1) == '*')
                    {
                        ++nestCount;
                    }
                    else if (stream.Peek() == '*' && stream.Peek(1) == '/')
                    {
                        --nestCount;
                    }
                    else
                    {
                        ++stream.Position;
                        continue;
                    }

                    stream.Position += 2;

                    if (stream.Read() == StringStream.NewLine)
                    {
                        ++Line;
                    }
                }

                return(true);
            }

            return(false);
        }
示例#4
0
        private static bool ParseDelimiter(StringStream stream, ICollection <Token> tokens)
        {
            bool   foundDelimiter  = false;
            string peekedDelimiter = "";

            foreach (string delimiter in Delimiters)
            {
                peekedDelimiter = "";

                for (int i = 0; i < delimiter.Length; ++i)
                {
                    peekedDelimiter += stream.Peek(i);
                }

                if (peekedDelimiter == delimiter)
                {
                    stream.Position += delimiter.Length;
                    foundDelimiter   = true;
                    break;
                }
            }

            if (foundDelimiter)
            {
                tokens.Add(new Token(TokenType.Delimiter, peekedDelimiter, Filename, Line));
                return(true);
            }

            return(false);
        }
示例#5
0
		public void Peek_NullString_ReturnsNullChar()
		{
			using (var scanner = new StringStream(null))
			{
				Assert.Equal('\0', scanner.Peek());
			}
		}
示例#6
0
 private static void SkipWhitespace(StringStream stream)
 {
     while (!stream.IsEndOfStream && char.IsWhiteSpace(stream.Peek()))
     {
         // Read new lines
         if (stream.Read() == StringStream.NewLine)
         {
             ++Line;
         }
     }
 }
示例#7
0
        private static string ParseEscapeSequence(string value)
        {
            StringStream stringStream = new StringStream(value);
            string       parsedValue  = "";

            while (!stringStream.IsEndOfStream)
            {
                // Read non-escaping characters
                if (stringStream.Peek() != '\\')
                {
                    parsedValue += stringStream.Read();
                    continue;
                }

                // Skip backslash
                stringStream.Read();

                switch (stringStream.Read())
                {
                case '\'':
                    parsedValue += '\'';
                    continue;

                case '\"':
                    parsedValue += '\"';
                    continue;

                case '\\':
                    parsedValue += '\\';
                    continue;

                case '%':
                    parsedValue += '%';
                    continue;

                case ':':
                    parsedValue += ':';
                    continue;

                case '\0':
                    parsedValue += '\0';
                    continue;

                case 'a':
                    parsedValue += '\a';
                    continue;

                case 'b':
                    parsedValue += '\b';
                    continue;

                case 'f':
                    parsedValue += '\f';
                    continue;

                case 'n':
                    parsedValue += '\n';
                    continue;

                case 'r':
                    parsedValue += '\r';
                    continue;

                case 't':
                    parsedValue += '\t';
                    continue;

                case 'u':
                case 'U':
                case 'x':
                {
                    string unicodeValue = "";

                    for (int i = 0; i < 8; ++i)
                    {
                        char read = stringStream.Read();
                        unicodeValue += read;

                        if (!stringStream.Peek(1).IsHex() && (i == 1 || i == 3 || i == 7))
                        {
                            break;
                        }
                    }

                    uint unicodeIntValue;
                    if (!uint.TryParse(unicodeValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out unicodeIntValue))
                    {
                        throw new LexerException("Malformed escape code \\x, \\u or \\U on line {0}.", Line);
                    }

                    parsedValue += Convert.ToChar(unicodeIntValue);
                    continue;
                }

                case 'v':
                    parsedValue += '\v';
                    continue;
                }

                throw new LexerException("Bad escape sequence.");
            }

            return(parsedValue);
        }
示例#8
0
        private static bool ParseNumber(StringStream stream, ICollection <Token> tokens)
        {
            if (char.IsDigit(stream.Peek()))
            {
                string number = "";

                if (stream.Peek() == '0' && stream.Peek(1) == 'x')
                {
                    stream.Position += 2;

                    while (!stream.IsEndOfStream && stream.Peek().IsHex())
                    {
                        number += stream.Read();
                    }

                    ulong result;
                    try
                    {
                        result = ulong.Parse(number, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
                    }
                    catch (OverflowException)
                    {
                        throw new LexerException("Number is larger than 64bits on line {0}.", Line);
                    }
                    catch (Exception)
                    {
                        throw new LexerException("Invalid number on line {0}.", Line);
                    }

                    number = result.ToString("G");
                }
                else if (stream.Peek() == '0' && stream.Peek(1) == 'b')
                {
                    stream.Position += 2;

                    while (!stream.IsEndOfStream && char.IsDigit(stream.Peek()))
                    {
                        number += stream.Read();
                    }

                    long result;
                    try
                    {
                        result = Convert.ToInt64(number, 2);
                    }
                    catch (OverflowException)
                    {
                        throw new LexerException("Number is larger than 64bits on line {0}.", Line);
                    }
                    catch (Exception)
                    {
                        throw new LexerException("Invalid number on line {0}.", Line);
                    }

                    number = result.ToString("G");
                }
                else
                {
                    while (!stream.IsEndOfStream && (char.IsDigit(stream.Peek()) || (stream.Peek() == '.' && stream.Peek(1) != '.')))
                    {
                        number += stream.Read();
                    }
                }

                tokens.Add(new Token(TokenType.Number, number, Filename, Line));

                return(true);
            }

            return(false);
        }
示例#9
0
		public void Peek_LongString_ReturnsSameAsPop()
		{
			const string input = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

			using (var scanner = new StringStream(input))
			{
				while (!scanner.IsCompleted)
				{
					char ch = scanner.Peek();
					Assert.Equal(scanner.Pop(), ch);
				}

				Assert.Equal(true, scanner.IsCompleted);
			}
		}