Skip to content

Commit d5ac8ff

Browse files
committed
Expressions
1 parent 10ebcbe commit d5ac8ff

File tree

6 files changed

+228
-18
lines changed

6 files changed

+228
-18
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Collections.Generic;
2+
using Pidgin;
3+
4+
namespace SimpleStateMachine.StructuralSearch.Sandbox.Extensions
5+
{
6+
public static class CharParserExtensions
7+
{
8+
public static Parser<TToken, string> AsString<TToken>(this Parser<TToken, char> parser)
9+
{
10+
return parser.Select(x => x.ToString());
11+
}
12+
}
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Pidgin;
3+
using static Pidgin.Parser;
4+
5+
namespace SimpleStateMachine.StructuralSearch.Sandbox.Extensions
6+
{
7+
public static class ManyParserExtensions
8+
{
9+
public static Parser<TToken, IEnumerable<T>> ToIEnumerable<TToken, T>(this Parser<TToken, List<T>> parser)
10+
{
11+
return parser.Cast<IEnumerable<T>>();
12+
}
13+
}
14+
}

src/SimpleStateMachine.StructuralSearch.Sandbox/Extensions/ParserExtensions.cs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
using System;
22
using Pidgin;
33
using Pidgin.Configuration;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
7+
using System.Linq;
8+
using Pidgin;
9+
using Pidgin.Expression;
10+
using SimpleStateMachine.StructuralSearch.Sandbox.Extensions;
11+
using static Pidgin.Parser;
12+
using static Pidgin.Parser<char>;
13+
using String = System.String;
414

515
namespace SimpleStateMachine.StructuralSearch.Sandbox.Extensions
616
{
@@ -12,7 +22,7 @@ public static class ParserExtensions
1222
// parser.Select()
1323
// return this.Select<U>((Func<T, U>)(_ => result));
1424
// }
15-
25+
1626
// public static Parser<TToken, T> BetweenWithLookahead<TToken, T, U, V>(this Parser<TToken, T> parser, Parser<TToken, U> parser1, Parser<TToken, V> parser2)
1727
// {
1828
// if (parser1 == null)
@@ -22,13 +32,51 @@ public static class ParserExtensions
2232
//
2333
// return Parser.Map((Func<U, T, V, T>) ((_, t, _) => t), parser1, parser, parser2);
2434
// }
25-
35+
2636
public static Parser<TToken, T> Try<TToken, T>(this Parser<TToken, T> parser)
2737
{
2838
return Parser.Try(parser);
2939
}
30-
31-
40+
41+
// public Parser<TToken, T> Between<U, V>(
42+
// Parser<TToken, U> parser1,
43+
// Parser<TToken, V> parser2)
44+
// {
45+
// if (parser1 == null)
46+
// throw new ArgumentNullException(nameof (parser1));
47+
// if (parser2 == null)
48+
// throw new ArgumentNullException(nameof (parser2));
49+
// return Parser.Map<TToken, U, T, V, T>((Func<U, T, V, T>) ((u, t, v) => t), parser1, this, parser2);
50+
// }
51+
public static Parser<TToken, T> WithDebug<TToken, T>(this Parser<TToken, T> parser, string label)
52+
{
53+
return Map((u, t, v) =>
54+
{
55+
Console.WriteLine($"{label} ({t.Col}) : {u} ");
56+
return u;
57+
}, parser, Parser<TToken>.CurrentPos, Parser<TToken>.CurrentSourcePosDelta);
58+
}
59+
60+
public static Parser<TToken, T> BetweenAsThen<TToken, T, U, V>(this Parser<TToken, T> parser,
61+
Parser<TToken, U> parser1,
62+
Parser<TToken, V> parser2, Func<U, T, V, T> func)
63+
{
64+
if (parser1 == null)
65+
throw new ArgumentNullException(nameof(parser1));
66+
if (parser2 == null)
67+
throw new ArgumentNullException(nameof(parser2));
68+
return Parser.Map<TToken, U, T, V, T>(func, parser1, parser, parser2);
69+
}
70+
// public static Parser<TToken, T> BetweenAsThen<TToken, T, U, V>(this Parser<TToken, T> parser, Parser<TToken, U> parser1, Parser<TToken, V> parser2, Func<U, T, V, T> func)
71+
// {
72+
// if (parser1 == null)
73+
// throw new ArgumentNullException(nameof (parser1));
74+
// if (parser2 == null)
75+
// throw new ArgumentNullException(nameof (parser2));
76+
//
77+
// return Parser.Map<TToken, T, T, T, T>(func, parser1, this, parser2);
78+
// }
79+
3280
// public static Parser<TToken, T> Between<TToken, T, U,V>(this Parser<TToken, T> parser,
3381
// Parser<TToken, U> parser1,
3482
// Parser<TToken, V> parser2)
@@ -39,7 +87,7 @@ public static Parser<TToken, T> Try<TToken, T>(this Parser<TToken, T> parser)
3987
// throw new ArgumentNullException(nameof (parser2));
4088
// return Parser.Map<TToken, U, T, V, T>((Func<U, T, V, T>) ((u, t, v) => t), parser1, this, parser2);
4189
// }
42-
90+
4391
// public static T ParseOrThrow<T>(this Parser<char, T> parser,
4492
// string input,
4593
// IConfiguration<char>? configuration = null)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Pidgin;
4+
5+
namespace SimpleStateMachine.StructuralSearch.Sandbox.Extensions
6+
{
7+
public static class StringParserExtensions
8+
{
9+
public static Parser<TToken, string> BetweenAsThen<TToken>(this Parser<TToken, string> parser,
10+
Parser<TToken, char> parser1,
11+
Parser<TToken, char> parser2)
12+
{
13+
if (parser1 == null)
14+
throw new ArgumentNullException(nameof(parser1));
15+
if (parser2 == null)
16+
throw new ArgumentNullException(nameof(parser2));
17+
18+
return Parser.Map<TToken, char, string, char, string>(
19+
(before, str, after) => before + str + after,
20+
parser1, parser, parser2);
21+
}
22+
23+
public static Parser<TToken, string> BetweenAsThen<TToken>(this Parser<TToken, string> parser,
24+
Parser<TToken, string> parser1,
25+
Parser<TToken, string> parser2)
26+
{
27+
if (parser1 == null)
28+
throw new ArgumentNullException(nameof(parser1));
29+
if (parser2 == null)
30+
throw new ArgumentNullException(nameof(parser2));
31+
32+
return Parser.Map<TToken, string, string, string, string>(
33+
(before, str, after) => before + str + after,
34+
parser1, parser, parser2);
35+
}
36+
37+
// public static Parser<TToken, IEnumerable<string>> ToMany<TToken>(this Parser<TToken, string> parser)
38+
// {
39+
// return parser.Select(x => new List<string>() { x }).ToIEnumerable();
40+
// }
41+
public static Parser<TToken, List<string>> ToMany<TToken>(this Parser<TToken, string> parser)
42+
{
43+
return parser.Select(x => new List<string>{ x });
44+
}
45+
}
46+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Pidgin;
5+
using static Pidgin.Parser;
6+
7+
namespace SimpleStateMachine.StructuralSearch.Sandbox
8+
{
9+
public static class Parsers
10+
{
11+
public static Parser<char, string> Stringc(char character) => String(character.ToString());
12+
13+
public static Parser<TToken, List<T>> MapToMany<TToken, T>(Parser<TToken, T> parser1, Parser<TToken, T> parser2, Parser<TToken, T> parser3)
14+
{
15+
if (parser1 == null)
16+
throw new ArgumentNullException(nameof(parser1));
17+
if (parser2 == null)
18+
throw new ArgumentNullException(nameof(parser2));
19+
if (parser3 == null)
20+
throw new ArgumentNullException(nameof(parser2));
21+
22+
return Map((arg1, arg2, arg3) => new List<T>{arg1, arg2, arg3}, parser1, parser2, parser2);
23+
}
24+
25+
public static Parser<TToken, List<T>> MapToMany<TToken, T>(Parser<TToken, T> parser1, Parser<TToken, List<T>> parser2, Parser<TToken, T> parser3)
26+
{
27+
if (parser1 == null)
28+
throw new ArgumentNullException(nameof(parser1));
29+
if (parser2 == null)
30+
throw new ArgumentNullException(nameof(parser2));
31+
if (parser3 == null)
32+
throw new ArgumentNullException(nameof(parser2));
33+
34+
return Map((arg1, arg2, arg3) =>
35+
{
36+
arg2.Insert(0, arg1);
37+
arg2.Add(arg3);
38+
return arg2;
39+
}, parser1, parser2, parser3);
40+
}
41+
42+
public static Parser<TToken, List<T>> MapToMany<TToken, T>(Parser<TToken, T> parser1, Parser<TToken, IEnumerable<T>> parser2, Parser<TToken, T> parser3)
43+
{
44+
if (parser1 == null)
45+
throw new ArgumentNullException(nameof(parser1));
46+
if (parser2 == null)
47+
throw new ArgumentNullException(nameof(parser2));
48+
if (parser3 == null)
49+
throw new ArgumentNullException(nameof(parser2));
50+
51+
return Map((arg1, arg2, arg3) =>
52+
{
53+
var result = arg2.ToList();
54+
result.Insert(0, arg1);
55+
result.Add(arg3);
56+
return result;
57+
}, parser1, parser2, parser3);
58+
}
59+
}
60+
}

src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Pidgin.Expression;
66
using SimpleStateMachine.StructuralSearch.Sandbox.Extensions;
77
using static Pidgin.Parser;
8+
using static SimpleStateMachine.StructuralSearch.Sandbox.Parsers;
89
using static Pidgin.Parser<char>;
910
using String = System.String;
1011

@@ -14,32 +15,58 @@ internal static class Program
1415
{
1516
private static Parser<char, T> Parenthesised<T>(Parser<char, T> parser)
1617
=> parser.Between(String("("), String(")"));
18+
1719
public class Placeholder
1820
{
1921
public Placeholder(bool isCorrect, string value)
2022
{
2123
IsCorrect = isCorrect;
2224
Value = value;
2325
}
24-
26+
2527
public bool IsCorrect { get; set; }
2628
public string Value { get; set; }
2729
}
30+
2831
static void Main(string[] args)
2932
{
30-
var placeholder = PlaceholderParser.Identifier.Between(Char('$'));
33+
var whitespaces = WhitespaceString;
34+
var endOfLines = EndOfLine.ManyString();
35+
var anyCharExcept = AnyCharExcept('(', ')', '[', ']', '{', '}', '$', ' ', '\n').AtLeastOnceString().Try()
36+
.WithDebug("anyCharExcept");
37+
Parser<char, IEnumerable<string>> expr = null;
38+
var placeholder = PlaceholderParser.Identifier.Between(Char('$')).Try()
39+
.WithDebug("placeholder");
40+
var parenthesised1 = MapToMany(Stringc('('), Rec(() => expr), Stringc(')'))
41+
.WithDebug("parenthesised1");
42+
var parenthesised2 = MapToMany(Stringc('['), Rec(() => expr), Stringc(']'))
43+
.WithDebug("parenthesised2");
44+
var parenthesised3 = MapToMany(Stringc('{'), Rec(() => expr), Stringc('}'))
45+
.WithDebug("parenthesised3");
3146

32-
//expressions parser
33-
Parser<char, string> expr = null;
34-
Parser<char, string> parenthesised = Rec(() => expr).Between(Char('('), Char(')'));
35-
expr = AnyCharExcept('(', ')').ManyString().Or(parenthesised);
36-
47+
// var parenthesised1 = Rec(() => expr)
48+
// .Between(Char('('), Char(')'))
49+
// .WithDebug("parenthesised1");
50+
// var parenthesised2 = Rec(() => expr)
51+
// .Between(Char('['), Char(']'))
52+
// .WithDebug("parenthesised1");
53+
// var parenthesised3 = Rec(() => expr)
54+
// .Between(Char('{'), Char('}'))
55+
// .WithDebug("parenthesised1");
3756

57+
var parenthesised = parenthesised1.Or(parenthesised2).Or(parenthesised3);
58+
59+
// var parser = anyCharExcept.Or(placeholder).Or(whitespaces).Or(endOfLines).Many();
60+
var parser = anyCharExcept.Or(placeholder).Separated(Whitespaces);
61+
62+
expr = parser.Or(parenthesised.ToIEnumerable());
63+
64+
3865
var t = "((test > 25) && (test < 50))";
39-
66+
var t2 = "([test > 25] && {test < 50})";
4067
//template parser
4168
var separator = Whitespaces.AsString().Or(EndOfLine);
42-
var any = AnyCharExcept('$', ' ', '\n').AtLeastOnceString();
69+
var any = AnyCharExcept('$', ' ', '\n').AtLeastOnceString();
4370
var token = PlaceholderParser.Identifier.Between(Char('$')).Try();
4471
var templateParser = token.Or(any).Separated(separator);
4572

@@ -48,14 +75,16 @@ static void Main(string[] args)
4875
.Then(Char('('))
4976
.Then(Any.Until(Lookahead(Char(')').Then(End).Try())))
5077
.AsString();
51-
78+
5279
var template =
53-
"if($condition$)\n" +
80+
"if(($condition$) = ($test$))\n" +
5481
"return $value1$;\n" +
5582
"else\n" +
5683
"return $value2$;";
57-
var test = templateParser.ParseOrThrow(template);
58-
84+
85+
var template2 = "((test)=(test2))";
86+
var template3 = "$test1$ test test34";
87+
var test = expr.ParseOrThrow(template);
5988
}
6089
}
6190
}

0 commit comments

Comments
 (0)