diff --git a/Lexer.Tests/MLexerShould.cs b/Lexer.Tests/MLexerShould.cs index a75bbe3..64bf718 100644 --- a/Lexer.Tests/MLexerShould.cs +++ b/Lexer.Tests/MLexerShould.cs @@ -225,5 +225,14 @@ namespace Parser.Tests Assert.AreEqual(TokenKind.StringLiteral, tokens[0].Kind); Assert.AreEqual("just a 'string'", tokens[0].PureToken.Value); } + + [Test] + public void ParseNumberStartingWithDot() + { + var sut = CreateLexer(".42"); + var tokens = sut.ParseAll(); + Assert.AreEqual(2, tokens.Count); + Assert.AreEqual(TokenKind.NumberLiteral, tokens[0].Kind); + } } } \ No newline at end of file diff --git a/Lexer/MLexer.cs b/Lexer/MLexer.cs index d9d4d80..f0a3e0f 100644 --- a/Lexer/MLexer.cs +++ b/Lexer/MLexer.cs @@ -150,6 +150,11 @@ namespace Lexer return c >= '0' && c <= '9'; } + private static bool IsDigitOrDot(char c) + { + return c == '.' || (c >= '0' && c <= '9'); + } + private static bool IsWhitespace(char c) { return c == ' ' || c == '\t' || c == '\n'; @@ -168,7 +173,7 @@ namespace Lexer switch (state) { case NumberParsingState.Start: - if (IsDigit(c)) + if (IsDigitOrDot(c)) { state = NumberParsingState.DigitsBeforeDot; } @@ -438,6 +443,15 @@ namespace Lexer return PureTokenFactory.CreatePunctuation(TokenKind.Assignment); case '.': + if (IsDigit(Window.PeekChar(1))) + { + var possiblyNumberToken2 = ContinueParsingNumber(); + if (possiblyNumberToken2 == null) + { + throw new ParsingException($"Unexpected character \"{Window.PeekChar()}\" while parsing a number"); + } + return (PureToken)possiblyNumberToken2; + } Window.ConsumeChar(); var c = Window.PeekChar(); switch (c)