From 653c9fcce692a9407e433b4e3ae5c8adf1a33f74 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 10 Jun 2025 15:43:38 -0700 Subject: [PATCH] Consume decimal separator when accepted --- src/Parlot/Scanner.cs | 4 ++-- test/Parlot.Tests/ScannerTests.cs | 26 +++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Parlot/Scanner.cs b/src/Parlot/Scanner.cs index b22fa31..343acff 100644 --- a/src/Parlot/Scanner.cs +++ b/src/Parlot/Scanner.cs @@ -201,11 +201,11 @@ public bool ReadDecimal(bool allowLeadingSign, bool allowDecimalSeparator, bool if (!ReadInteger(out number)) { - Cursor.ResetPosition(beforeDecimalSeparator); - // A decimal separator must be followed by a number if there is no integral part, e.g. `[NaN].[NaN]` if (numberIsEmpty) { + Cursor.ResetPosition(beforeDecimalSeparator); + return false; } diff --git a/test/Parlot.Tests/ScannerTests.cs b/test/Parlot.Tests/ScannerTests.cs index b69e096..08510dd 100644 --- a/test/Parlot.Tests/ScannerTests.cs +++ b/test/Parlot.Tests/ScannerTests.cs @@ -1,7 +1,7 @@ using Parlot.Tests.Calc; using System; using System.Buffers; - +using System.Globalization; using Xunit; namespace Parlot.Tests; @@ -401,14 +401,34 @@ public void ShouldReadDecimalWithGroupSeparator(string input, string expected) [Theory] [InlineData("123.456", "123.456")] [InlineData("123.456a", "123.456")] - [InlineData("123.a", "123")] + [InlineData("123.a", "123.")] [InlineData("123.456.789", "123.456")] - [InlineData("123.", "123")] + [InlineData("123.", "123.")] public void ShouldReadDecimalWithDecimalSeparator(string input, string expected) { Scanner s = new(input); Assert.True(s.ReadDecimal(Fluent.NumberOptions.AllowDecimalSeparator, out var result, decimalSeparator: '.')); + Assert.True(decimal.TryParse(expected, NumberStyles.Float, CultureInfo.InvariantCulture, out _)); + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("123.456", "123")] + [InlineData("123.456a", "123")] + [InlineData("123.a", "123")] + [InlineData("123.456.789", "123")] + [InlineData("123.", "123")] + [InlineData("123.e", "123")] + [InlineData("123.e1", "123")] + [InlineData("123e", "123")] + [InlineData("123e1", "123e1")] + public void ShouldReadIntegerWithExponent(string input, string expected) + { + Scanner s = new(input); + + Assert.True(s.ReadDecimal(Fluent.NumberOptions.Integer | Fluent.NumberOptions.AllowExponent, out var result, decimalSeparator: '.')); + Assert.True(decimal.TryParse(expected, NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out _)); Assert.Equal(expected, result); } }