-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExpressionParser.cs
More file actions
50 lines (39 loc) · 1.37 KB
/
ExpressionParser.cs
File metadata and controls
50 lines (39 loc) · 1.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using Ramstack.Parsing;
using static Ramstack.Parsing.Parser;
namespace Samples;
public static class ExpressionParser
{
public static readonly Parser<double> Parser = CreateExpressionParser();
private static Parser<double> CreateExpressionParser()
{
// Grammar:
// ----------------------------------------
// Start : Sum $
// Sum : Product (S [+-] Product)*
// Product : Unary (S [*/] Unary)*
// Unary : S '-'? Primary
// Primary : Parenthesis / Value
// Parenthesis : S '(' Sum S ')'
// Value : S Number
// S : Whitespace*
var sum = Deferred<double>();
var number = S.Then(Literal.Number<double>("number"));
var parenthesis = sum.Between(
Seq(S, L('(')),
Seq(S, L(')'))
);
var primary = parenthesis.Or(number);
var unary = Seq(
S,
L('-').Optional(),
primary
).Do((_, u, d) => u.HasValue ? -d : d);
var product = unary.Fold(
S.Then(OneOf("*/")),
(l, r, o) => o == '*' ? l * r : l / r);
sum.Parser = product.Fold(
S.Then(OneOf("+-")),
(l, r, o) => o == '+' ? l + r : l - r);
return sum.Before(Eof);
}
}