Skip to content

Commit

Permalink
Create Number parser (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienros authored Jun 15, 2024
1 parent d0814f0 commit afc46f5
Show file tree
Hide file tree
Showing 27 changed files with 1,137 additions and 710 deletions.
31 changes: 25 additions & 6 deletions docs/parsers.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Result:

### Integer

Matches an integral numeric value. By default the plus `+` and `-` signs are not parsed unless the `NumberOptions.AllowSign` is specified.
Matches an integral numeric value and an optional leading sign.

```c#
Parser<long> Integer()
Expand All @@ -106,18 +106,17 @@ Usage:

```c#
var input = "-1234";
var parser = Terms.Integer(NumberOptions.AllowSign);
```

Result:

```
-1,234
-1234
```

### Decimal

Matches a numeric value with optional digits. By default the plus `+` and `-` signs are not parsed unless the `NumberOptions.AllowSign` is specified.
Matches a numeric value with optional digits and leading sign. The exponent is supported.

```c#
Parser<decimal> Decimal()
Expand All @@ -133,10 +132,30 @@ var parser = Terms.Decimal(NumberOptions.AllowSign);
Result:

```
-1,234.56
-1234.56
```

The parsers `Float` and `Double` are identical to `Decimal` with the difference that they return `float` and `double` respectively.
### Number

Matches a numeric value of any .NET type. The `NumberOptions` enumeration enables to customize how the number is parsed.
The return type can be any numeric .NET type that is compatible with the selected options.

```c#
Parser<T> Number() where T : INumber<T>
```

Usage:

```c#
var input = "-1,234.56e1";
var parser = Terms.Number<double>(NumberOptions.Float | NumberOptions.AllowGroupSeparators);
```

Result:

```
-12345.6
```

### String

Expand Down
1 change: 1 addition & 0 deletions src/Parlot/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal enum CharacterMask : byte

public static partial class Character
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsDecimalDigit(char ch) => IsInRange(ch, '0', '9');

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
2 changes: 1 addition & 1 deletion src/Parlot/Compilation/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Parlot.Compilation
{
/// <summary>
/// Reprensents the context of a compilation phase, coordinating all the parsers involved.
/// Represents the context of a compilation phase, coordinating all the parsers involved.
/// </summary>
public class CompilationContext
{
Expand Down
20 changes: 17 additions & 3 deletions src/Parlot/Compilation/ExpressionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ namespace Parlot.Compilation
public static class ExpressionHelper
{
internal static MethodInfo ParserContext_SkipWhiteSpaceMethod = typeof(ParseContext).GetMethod(nameof(ParseContext.SkipWhiteSpace), Array.Empty<Type>());
internal static MethodInfo Scanner_ReadText = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadText), [typeof(string), typeof(StringComparison), typeof(TokenResult)]);
internal static MethodInfo Scanner_ReadText_NoResult = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadText), [typeof(string), typeof(StringComparison)]);
internal static MethodInfo Scanner_ReadChar = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadChar), [typeof(char)]);
internal static MethodInfo Scanner_ReadDecimal = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadDecimal), []);
internal static MethodInfo Scanner_ReadDecimalAllArguments = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadDecimal), [typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(ReadOnlySpan<char>).MakeByRefType(), typeof(char), typeof(char)]);
internal static MethodInfo Scanner_ReadInteger = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadInteger), []);
internal static MethodInfo Scanner_ReadNonWhiteSpace = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadNonWhiteSpace), []);
internal static MethodInfo Scanner_ReadNonWhiteSpaceOrNewLine = typeof(Scanner).GetMethod(nameof(Parlot.Scanner.ReadNonWhiteSpaceOrNewLine), []);
Expand All @@ -39,7 +39,7 @@ public static class ExpressionHelper
public static MemberExpression Position(this CompilationContext context) => Expression.Property(context.Cursor(), "Position");
public static Expression ResetPosition(this CompilationContext context, Expression position) => Expression.Call(context.Cursor(), typeof(Cursor).GetMethod("ResetPosition"), position);
public static MemberExpression Offset(this CompilationContext context) => Expression.Property(context.Cursor(), "Offset");
public static MemberExpression Offset(this CompilationContext context, Expression textPosition) => Expression.Field(textPosition, nameof(TextPosition.Offset));
public static MemberExpression Offset(this CompilationContext _, Expression textPosition) => Expression.Field(textPosition, nameof(TextPosition.Offset));
public static MemberExpression Current(this CompilationContext context) => Expression.Property(context.Cursor(), "Current");
public static MemberExpression Eof(this CompilationContext context) => Expression.Property(context.Cursor(), "Eof");
public static MemberExpression Buffer(this CompilationContext context) => Expression.Field(context.Scanner(), "Buffer");
Expand All @@ -51,6 +51,7 @@ public static class ExpressionHelper
public static MethodCallExpression ReadQuotedString(this CompilationContext context) => Expression.Call(context.Scanner(), Scanner_ReadQuotedString);
public static MethodCallExpression ReadChar(this CompilationContext context, char c) => Expression.Call(context.Scanner(), Scanner_ReadChar, Expression.Constant(c));
public static MethodCallExpression ReadDecimal(this CompilationContext context) => Expression.Call(context.Scanner(), Scanner_ReadDecimal);
public static MethodCallExpression ReadDecimal(this CompilationContext context, Expression allowLeadingSign, Expression allowDecimalSeparator, Expression allowGroupSeparator, Expression allowExponent, Expression number, Expression decimalSeparator, Expression groupSeparator) => Expression.Call(context.Scanner(), Scanner_ReadDecimalAllArguments, allowLeadingSign, allowDecimalSeparator, allowGroupSeparator, allowExponent, number, decimalSeparator, groupSeparator);
public static MethodCallExpression ReadInteger(this CompilationContext context) => Expression.Call(context.Scanner(), Scanner_ReadInteger);
public static MethodCallExpression ReadNonWhiteSpace(this CompilationContext context) => Expression.Call(context.Scanner(), Scanner_ReadNonWhiteSpace);
public static MethodCallExpression ReadNonWhiteSpaceOrNewLine(this CompilationContext context) => Expression.Call(context.Scanner(), Scanner_ReadNonWhiteSpaceOrNewLine);
Expand All @@ -67,7 +68,7 @@ public static ParameterExpression DeclareSuccessVariable(this CompilationContext
return result.Success;
}

public static ParameterExpression DeclareVariable<T>(this CompilationContext context, CompilationResult result, string name, Expression defaultValue = null)
public static ParameterExpression DeclareVariable<T>(this CompilationContext _, CompilationResult result, string name, Expression defaultValue = null)
{
var variable = Expression.Variable(typeof(T), name);
result.Variables.Add(variable);
Expand All @@ -77,6 +78,19 @@ public static ParameterExpression DeclareVariable<T>(this CompilationContext con
return variable;
}

public static ParameterExpression DeclareVariable(this CompilationContext _, CompilationResult result, string name, Type type, Expression defaultValue = null)
{
var variable = Expression.Variable(type, name);
result.Variables.Add(variable);

if (defaultValue != null)
{
result.Body.Add(Expression.Assign(variable, defaultValue));
}

return variable;
}

public static ParameterExpression DeclareValueVariable<T>(this CompilationContext context, CompilationResult result)
{
return DeclareValueVariable(context, result, Expression.Default(typeof(T)));
Expand Down
138 changes: 0 additions & 138 deletions src/Parlot/Fluent/DecimalLiteral.cs

This file was deleted.

Loading

0 comments on commit afc46f5

Please sign in to comment.