Skip to content

Commit aff0f5e

Browse files
committed
Rule parsing
1 parent 44a1ef8 commit aff0f5e

File tree

24 files changed

+407
-153
lines changed

24 files changed

+407
-153
lines changed

src/SimpleStateMachine.StructuralSearch.Sandbox/Expr.cs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace SimpleStateMachine.StructuralSearch.Sandbox
66
{
7-
public interface IExpr : IEquatable<IExpr>
7+
public interface IExpr
88
{
9+
public double Invoke();
910
}
1011

1112
public class Identifier : IExpr
@@ -19,19 +20,29 @@ public Identifier(string name)
1920

2021
public bool Equals(IExpr? other)
2122
=> other is Identifier i && this.Name == i.Name;
23+
24+
public double Invoke()
25+
{
26+
return 0;
27+
}
2228
}
2329

2430
public class Literal : IExpr
2531
{
26-
public int Value { get; }
32+
public double Value { get; }
2733

28-
public Literal(int value)
34+
public Literal(double value)
2935
{
3036
Value = value;
3137
}
3238

3339
public bool Equals(IExpr? other)
3440
=> other is Literal l && this.Value == l.Value;
41+
42+
public double Invoke()
43+
{
44+
return Value;
45+
}
3546
}
3647

3748
public class Call : IExpr
@@ -49,12 +60,19 @@ public bool Equals(IExpr? other)
4960
=> other is Call c
5061
&& ((Object)this.Expr).Equals(c.Expr)
5162
&& this.Arguments.SequenceEqual(c.Arguments);
63+
64+
public double Invoke()
65+
{
66+
throw new NotImplementedException();
67+
}
5268
}
5369

5470
public enum UnaryOperatorType
5571
{
56-
Neg,
57-
Complement
72+
Increment,
73+
Decrement,
74+
Plus,
75+
Minus
5876
}
5977
public class UnaryOp : IExpr
6078
{
@@ -71,12 +89,26 @@ public bool Equals(IExpr? other)
7189
=> other is UnaryOp u
7290
&& this.Type == u.Type
7391
&& ((Object)this.Expr).Equals(u.Expr);
92+
93+
public double Invoke()
94+
{
95+
return Type switch
96+
{
97+
UnaryOperatorType.Increment => Expr.Invoke() + 1,
98+
UnaryOperatorType.Decrement => Expr.Invoke() - 1,
99+
UnaryOperatorType.Plus => - Expr.Invoke(),
100+
UnaryOperatorType.Minus => + Expr.Invoke(),
101+
_ => throw new ArgumentOutOfRangeException()
102+
};
103+
}
74104
}
75105

76106
public enum BinaryOperatorType
77107
{
78-
Add,
79-
Mul
108+
Add, // +
109+
Sub, // -
110+
Mul, // *
111+
Div, // /
80112
}
81113
public class BinaryOp : IExpr
82114
{
@@ -96,5 +128,16 @@ public bool Equals(IExpr? other)
96128
&& this.Type == b.Type
97129
&& ((Object)this.Left).Equals(b.Left)
98130
&& ((Object)this.Right).Equals(b.Right);
131+
132+
public double Invoke()
133+
{
134+
return Type switch
135+
{
136+
BinaryOperatorType.Add => Left.Invoke() + Right.Invoke(),
137+
BinaryOperatorType.Mul => Left.Invoke() * Right.Invoke(),
138+
BinaryOperatorType.Div => Left.Invoke() / Right.Invoke(),
139+
BinaryOperatorType.Sub => Left.Invoke() - Right.Invoke(),
140+
};
141+
}
99142
}
100143
}

src/SimpleStateMachine.StructuralSearch.Sandbox/ExprParser.cs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,81 @@
33
using Pidgin;
44
using Pidgin.Expression;
55

6+
using System;
7+
using System.Collections.Immutable;
8+
using Pidgin;
9+
using Pidgin.Expression;
10+
using static Pidgin.Parser;
11+
using static Pidgin.Parser<char>;
12+
613
namespace SimpleStateMachine.StructuralSearch.Sandbox
714
{
8-
public static class ExprParser
15+
public static class ExprParser
916
{
1017
private static Parser<char, T> Tok<T>(Parser<char, T> token)
11-
=> Parser.Try(token).Before(Parser.SkipWhitespaces);
18+
=> Try(token).Before(SkipWhitespaces);
1219
private static Parser<char, string> Tok(string token)
13-
=> Tok(Parser.String(token));
20+
=> Tok(String(token));
1421

1522
private static Parser<char, T> Parenthesised<T>(Parser<char, T> parser)
1623
=> parser.Between(Tok("("), Tok(")"));
17-
24+
1825
private static Parser<char, Func<IExpr, IExpr, IExpr>> Binary(Parser<char, BinaryOperatorType> op)
1926
=> op.Select<Func<IExpr, IExpr, IExpr>>(type => (l, r) => new BinaryOp(type, l, r));
2027
private static Parser<char, Func<IExpr, IExpr>> Unary(Parser<char, UnaryOperatorType> op)
2128
=> op.Select<Func<IExpr, IExpr>>(type => o => new UnaryOp(type, o));
2229

2330
private static readonly Parser<char, Func<IExpr, IExpr, IExpr>> Add
2431
= Binary(Tok("+").ThenReturn(BinaryOperatorType.Add));
32+
private static readonly Parser<char, Func<IExpr, IExpr, IExpr>> Sub
33+
= Binary(Tok("-").ThenReturn(BinaryOperatorType.Sub));
34+
private static readonly Parser<char, Func<IExpr, IExpr, IExpr>> Div
35+
= Binary(Tok("/").ThenReturn(BinaryOperatorType.Div));
2536
private static readonly Parser<char, Func<IExpr, IExpr, IExpr>> Mul
2637
= Binary(Tok("*").ThenReturn(BinaryOperatorType.Mul));
27-
private static readonly Parser<char, Func<IExpr, IExpr>> Neg
28-
= Unary(Tok("-").ThenReturn(UnaryOperatorType.Neg));
29-
private static readonly Parser<char, Func<IExpr, IExpr>> Complement
30-
= Unary(Tok("~").ThenReturn(UnaryOperatorType.Complement));
38+
private static readonly Parser<char, Func<IExpr, IExpr>> Decrement
39+
= Unary(Tok("--").ThenReturn(UnaryOperatorType.Decrement));
40+
private static readonly Parser<char, Func<IExpr, IExpr>> Increment
41+
= Unary(Tok("++").ThenReturn(UnaryOperatorType.Increment));
3142

43+
private static readonly Parser<char, Func<IExpr, IExpr>> Minus
44+
= Unary(Tok("-").ThenReturn(UnaryOperatorType.Minus));
45+
private static readonly Parser<char, Func<IExpr, IExpr>> Plus
46+
= Unary(Tok("+").ThenReturn(UnaryOperatorType.Plus));
47+
3248
private static readonly Parser<char, IExpr> Identifier
33-
= Tok(Parser.Letter.Then(Parser.LetterOrDigit.ManyString(), (h, t) => h + t))
49+
= Tok(Letter.Then(LetterOrDigit.ManyString(), (h, t) => h + t))
3450
.Select<IExpr>(name => new Identifier(name))
3551
.Labelled("identifier");
52+
3653
private static readonly Parser<char, IExpr> Literal
37-
= Tok(Parser.Num)
54+
= Tok(LongNum)
3855
.Select<IExpr>(value => new Literal(value))
3956
.Labelled("integer literal");
40-
41-
private static Parser<char, Func<IExpr, IExpr>> Call(Parser<char, IExpr> subExpr)
42-
=> Parenthesised(subExpr.Separated(Tok(",")))
43-
.Select<Func<IExpr, IExpr>>(args => method => new Call(method, args.ToImmutableArray()))
44-
.Labelled("function call");
45-
57+
4658
private static readonly Parser<char, IExpr> Expr = ExpressionParser.Build<char, IExpr>(
4759
expr => (
48-
Parser.OneOf(
60+
OneOf(
4961
Identifier,
5062
Literal,
5163
Parenthesised(expr).Labelled("parenthesised expression")
5264
),
5365
new[]
5466
{
55-
Operator.PostfixChainable(Call(expr)),
56-
Operator.Prefix(Neg).And(Operator.Prefix(Complement)),
67+
Operator.Prefix(Decrement)
68+
.And(Operator.Prefix(Increment))
69+
.And(Operator.Prefix(Minus))
70+
.And(Operator.Prefix(Plus)),
5771
Operator.InfixL(Mul),
58-
Operator.InfixL(Add)
72+
Operator.InfixL(Div),
73+
Operator.InfixL(Add),
74+
Operator.InfixL(Sub)
5975
}
6076
)
6177
).Labelled("expression");
6278

63-
public static IExpr ParseOrThrow(string input)
64-
=> Expr.ParseOrThrow(input);
79+
public static IExpr ParseOrThrow(string input)
80+
=> Expr.ParseOrThrow(input);
81+
6582
}
6683
}

src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ internal static class Program
1010
{
1111
static void Main(string[] args)
1212
{
13-
var str = Console.ReadLine();
14-
var parser = (Parser.String("test").Trim().Then(Parser.Num.Between(Char('"')))).Between(Char('"'));
15-
var res1 = parser.ParseOrThrow(str);
16-
var t = ExprParser.ParseOrThrow("10 + -5");
13+
var t = ExprParser.ParseOrThrow("( 2 + 2 ) * 2");
14+
var resw = t.Invoke();
1715
var test = String("return ")
1816
.Then(AnyCharExcept(';').ManyString())
1917
.Then(Char(';').AtLeastOnceString())
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace SimpleStateMachine.StructuralSearch.Tests
2+
{
3+
public class RuleParserTests
4+
{
5+
6+
}
7+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using SimpleStateMachine.StructuralSearch.Rules;
3+
4+
namespace SimpleStateMachine.StructuralSearch.Helper
5+
{
6+
public static class LogicalHelper
7+
{
8+
public static bool Calculate(BinaryRuleType type, bool left, bool right)
9+
{
10+
return type switch
11+
{
12+
BinaryRuleType.And => left && right,
13+
BinaryRuleType.Or => left || right,
14+
BinaryRuleType.NAND => !(left && right),
15+
BinaryRuleType.NOR => !(left || right),
16+
BinaryRuleType.XOR => left ^ right,
17+
BinaryRuleType.XNOR => left == right,
18+
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
19+
};
20+
}
21+
}
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using SimpleStateMachine.StructuralSearch.Helper;
2+
3+
namespace SimpleStateMachine.StructuralSearch.Rules
4+
{
5+
public class BinaryRule : IRule
6+
{
7+
public BinaryRuleType Type { get; }
8+
9+
public IRule Left { get; }
10+
11+
public IRule Right { get; }
12+
13+
public BinaryRule(BinaryRuleType type, IRule left, IRule right)
14+
{
15+
Type = type;
16+
Left = left;
17+
Right = right;
18+
}
19+
20+
public bool Execute(string value)
21+
{
22+
var left = Left.Execute(value);
23+
var right = Right.Execute(value);
24+
25+
return LogicalHelper.Calculate(Type, left, right);
26+
}
27+
}
28+
}

src/SimpleStateMachine.StructuralSearch/Rules/SubRule/BinarySubRuleType.cs renamed to src/SimpleStateMachine.StructuralSearch/Rules/BinaryRuleType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
namespace SimpleStateMachine.StructuralSearch.Rules
22
{
3-
public enum BinarySubRuleType
3+
public enum BinaryRuleType
44
{
55
And = 0,
66
Or,
7+
NAND,
78
NOR,
89
XOR,
9-
NAND,
1010
XNOR
1111
}
1212
}

src/SimpleStateMachine.StructuralSearch/Rules/IRule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
{
33
public interface IRule
44
{
5-
5+
bool Execute(string value);
66
}
77
}

src/SimpleStateMachine.StructuralSearch/Rules/IRulesMaster.cs renamed to src/SimpleStateMachine.StructuralSearch/Rules/IRuleParameter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace SimpleStateMachine.StructuralSearch.Rules
22
{
3-
public interface IRulesMaster
3+
public interface IRuleParameter
44
{
5-
5+
string GetValue();
66
}
77
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace SimpleStateMachine.StructuralSearch.Rules
6+
{
7+
public class InRule : IRule
8+
{
9+
public SubRuleType Type { get; }
10+
11+
public IEnumerable<IRuleParameter> Parameters { get; }
12+
13+
public InRule(SubRuleType type, IEnumerable<IRuleParameter> parameters)
14+
{
15+
Type = type;
16+
17+
Parameters = parameters;
18+
}
19+
20+
public bool Execute(string value)
21+
{
22+
return Parameters.Any(parameter => Equals(value, parameter.GetValue()));
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)