Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,40 @@ private static Parser<double> CreateParser()
{
// Grammar:
// ----------------------------------------
// Start : Sum $
// Sum : Product (S [+-] Product)*
// Product : Unary (S [*/] Unary)*
// Unary : S '-'? Primary
// Start : S Sum $
// Sum : Product ([+-] S Product)*
// Product : Unary ([*/] S Unary)*
// Unary : '-'? S Primary
// Primary : Parenthesis / Value
// Parenthesis : S '(' Sum S ')'
// Value : S Number
// S : Whitespace*
// Parenthesis : '(' S Sum ')' S
// Value : Number S
// S : [ \r\n\t]*

var sum = Deferred<double>();
var value = S.Then(Literal.Number<double>());
var value = Literal.Number<double>().ThenIgnore(S);

var parenthesis = sum.Between(
Seq(S, L('(')),
Seq(S, L(')'))
Seq(L('('), S),
Seq(L(')'), S)
);

var primary = parenthesis.Or(value);

var unary = Seq(
S,
L('-').Optional(),
S,
primary
).Do((_, u, d) => u.HasValue ? -d : d);
).Do((u, _, d) => u.HasValue ? -d : d);

var product = unary.Fold(
S.Then(OneOf("*/")),
OneOf("*/").ThenIgnore(S),
(l, r, op) => op == '*' ? l * r : l / r);

sum.Parser = product.Fold(
S.Then(OneOf("+-")),
OneOf("+-").ThenIgnore(S),
(l, r, op) => op == '+' ? l + r : l - r);

return sum.Before(Eof);
return sum.Between(S, Eof);
}
```

Expand Down
4 changes: 2 additions & 2 deletions benchmarks/Parsers/RamstackParsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ public static class RamstackParsers
{
public static readonly Parser<string> EmailParser = CreateEmailParser();
public static readonly Parser<Unit> EmailVoidParser = EmailParser.Void();
public static readonly Parser<double> ExpressionParser = Samples.ExpressionParser.Parser;
public static readonly Parser<object?> JsonParser = Samples.JsonParser.Parser;
public static readonly Parser<double> ExpressionParser = Samples.CalcExpr.ExpressionParser.Parser;
public static readonly Parser<object?> JsonParser = Samples.Json.JsonParser.Parser;

private static Parser<string> CreateEmailParser()
{
Expand Down
49 changes: 49 additions & 0 deletions samples/CalcExpr/ExpressionParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Diagnostics.CodeAnalysis;

using Ramstack.Parsing;

using static Ramstack.Parsing.Parser;

namespace Samples.CalcExpr;

public static class ExpressionParser
{
public static readonly Parser<double> Parser = CreateExpressionParser();

[SuppressMessage("ReSharper", "InconsistentNaming")]
private static Parser<double> CreateExpressionParser()
{
var sum_expr =
Deferred<double>();

var number_expr =
Literal.Number<double>("number").ThenIgnore(S);

var parenthesis_expr =
sum_expr.Between(
Seq(L('('), S),
Seq(L(')'), S));

var primary_expr =
parenthesis_expr.Or(number_expr);

var unary_expr =
Seq(
L('-').Optional(),
S,
primary_expr
).Do((u, _, d) => u.HasValue ? -d : d);

var mul_expr =
unary_expr.Fold(
OneOf("*/").ThenIgnore(S),
(l, r, o) => o == '*' ? l * r : l / r);

sum_expr.Parser =
mul_expr.Fold(
OneOf("+-").ThenIgnore(S),
(l, r, o) => o == '+' ? l + r : l - r);

return sum_expr.Between(S, Eof);
}
}
43 changes: 43 additions & 0 deletions samples/CalcExpr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Simple Calc

This project implements a simple mathematical expression parser.

## Simple Expression Grammar

```sh
start
= sum_expr EOF
;

sum_expr
= mul_expr (S [+-] mul_expr)*
;

mul_expr
= unary_expr (S [*/] unary_expr)*
;

unary_expr
= S "-"? primary_expr
;

primary_expr
= parenthesis_expr / number_expr
;

parenthesis_expr
= S "(" Sum S ")"
;

number_expr
= S [0-9]+
;

S
= [ \t\r\n]*
;

EOF:
= $
;
```
50 changes: 0 additions & 50 deletions samples/ExpressionParser.cs

This file was deleted.

60 changes: 60 additions & 0 deletions samples/Json/JsonParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Ramstack.Parsing;

using static Ramstack.Parsing.Literal;
using static Ramstack.Parsing.Parser;

namespace Samples.Json;

public static class JsonParser
{
public static readonly Parser<object?> Parser = CreateJsonParser();

private static Parser<object?> CreateJsonParser()
{
var value =
Deferred<object?>();

var @string =
DoubleQuotedString.Do(object? (s) => s);

var number =
Number<double>().Do(object? (n) => n);

var primitive = OneOf(["true", "false", "null"]).Do(s =>
{
object? r = null;
if (s.Length != 0 && s[0] != 'n')
r = s[0] == 't';
return r;
});

var array = value
.Separated(Seq(L(','), S))
.Between(
Seq(L('['), S),
Seq(L(']'), S))
.Do(object? (list) => list);

var member = Seq(
DoubleQuotedString, S, L(':'), S, value
).Do((name, _, _, _, v) => KeyValuePair.Create(name, v));

var @object = member
.Separated(Seq(L(','), S))
.Between(
Seq(L('{'), S),
Seq(L('}'), S))
.Do(object? (members) => new Dictionary<string, object?>(members));

value.Parser =
Choice(
@string,
number,
primitive,
array,
@object
).ThenIgnore(S);

return S.Then(value);
}
}
31 changes: 31 additions & 0 deletions samples/Json/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# JSON Parser

This project implements a simple JSON parser.

## JSON Grammar

```sh
start
= value $
;

value
= (object / array / string / number / "true" / "false" / "null") S
;

object
= "{" S (member ("," S member)*)? "}" S
;

member
= string ":" S value
;

array
= "[" S (value ("," S value)*)? "]" S
;

S
= [ \t\r\n]*
;
```
49 changes: 0 additions & 49 deletions samples/JsonParser.cs

This file was deleted.

Loading