Skip to content

Commit d4e514f

Browse files
committed
fix parsers
1 parent d5d6d1c commit d4e514f

File tree

15 files changed

+193
-129
lines changed

15 files changed

+193
-129
lines changed

src/SimpleStateMachine.StructuralSearch.Tests/FindTemplateParserTests.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ public static void FindTemplateFromFileParsingShouldBeSuccess(string templatePat
1616
{
1717
var findTemplate = File.ReadAllText(templatePath);
1818
var template = StructuralSearch.StructuralSearch.ParseFindTemplate(findTemplate);
19-
19+
2020
Assert.NotNull(template);
2121
}
22-
22+
2323
[Theory]
2424
[InlineData("FindTemplate/NullUnionOperator.txt", "Source/NullUnionOperator.txt")]
2525
[InlineData("FindTemplate/AssignmentNullUnionOperator.txt", "Source/AssignmentNullUnionOperator.txt")]
@@ -33,22 +33,27 @@ public static void SourceParsingBeFindTemplateShouldBeSuccess(string templatePat
3333
var findParser = StructuralSearch.StructuralSearch.ParseFindTemplate(findTemplate);
3434
var matches = findParser.Parse(input);
3535
Assert.Single(matches);
36-
36+
3737
var match = matches.First();
38-
38+
3939
Assert.NotNull(findParser);
4040
Assert.Equal(match.Match.Lenght, source.Length);
4141
}
42-
42+
4343
[Theory]
4444
[InlineData("( $var$")]
4545
public static void FindTemplateParsingShouldBeFail(string templateStr)
4646
{
4747
Assert.Throws<ParseException<char>>(() => StructuralSearch.StructuralSearch.ParseFindTemplate(templateStr));
4848
}
49-
49+
5050
[Theory]
51+
[InlineData("($var$)")]
52+
[InlineData("($var$)(123)")]
53+
[InlineData("($var$)( )")]
54+
[InlineData("($var$) ( )")]
5155
[InlineData("( $var$ )")]
56+
[InlineData("(123$var$)")]
5257
public static void FindTemplateParsingShouldBeSuccess(string templateStr)
5358
{
5459
var template = StructuralSearch.StructuralSearch.ParseFindTemplate(templateStr);

src/SimpleStateMachine.StructuralSearch.Tests/ParameterParserTests.cs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Pidgin;
2+
using SimpleStateMachine.StructuralSearch.Helper;
23
using SimpleStateMachine.StructuralSearch.StructuralSearch;
34
using Xunit;
45

@@ -8,6 +9,32 @@ public static class ParameterParserTests
89
{
910
[Theory]
1011
[InlineData("\\\"132\\\"")]
12+
[InlineData("132")]
13+
[InlineData(" ")]
14+
public static void OptionalStringParsingShouldBeSuccess(string str)
15+
{
16+
var result = ParametersParser.String.ParseOrThrow(str);
17+
result = EscapeHelper.Escape(result);
18+
Assert.Equal(result.ToLower(), str.ToLower());
19+
}
20+
21+
[Theory]
22+
[InlineData("(\\\"132\\\")")]
23+
[InlineData("(132)")]
24+
[InlineData("[(132)]")]
25+
[InlineData("{(())}")]
26+
[InlineData("()")]
27+
[InlineData("( )")]
28+
public static void StringInParenthesesParsingShouldBeSuccess(string str)
29+
{
30+
var result = ParametersParser.StringInParentheses.ParseOrThrow(str);
31+
result = EscapeHelper.Escape(result);
32+
Assert.Equal(result.ToLower(), str.ToLower());
33+
}
34+
35+
[Theory]
36+
[InlineData("(\\\"132\\\")")]
37+
[InlineData("\\\"132\\\"")]
1138
[InlineData("\\\"()(132)\\\"")]
1239
[InlineData("()(132)")]
1340
[InlineData("(132)")]
@@ -21,7 +48,7 @@ public static void StringParameterParsingShouldBeSuccess(string str)
2148
var parameterStr = parameter.ToString()?.ToLower();
2249
Assert.Equal(parameterStr?.ToLower(), str.ToLower());
2350
}
24-
51+
2552
[Theory]
2653
[InlineData("\"132\"")]
2754
[InlineData("( ")]
@@ -34,7 +61,16 @@ public static void StringParameterParsingShouldBeFail(string str)
3461
return result;
3562
});
3663
}
37-
64+
65+
[Theory]
66+
[InlineData("$var$")]
67+
public static void PlaceholderParameterParsingShouldBeSuccess(string str)
68+
{
69+
var parameter = ParametersParser.PlaceholderParameter.ParseOrThrow(str);
70+
var parameterStr = parameter.ToString().ToLower();
71+
Assert.Equal(parameterStr.ToLower(), str.ToLower());
72+
}
73+
3874
[Theory]
3975
[InlineData("\"132\"")]
4076
[InlineData("\"132$var1$\"")]
@@ -49,14 +85,14 @@ public static void StringFormatParameterParsingShouldBeSuccess(string str)
4985
var parameterStr = parameter.ToString()?.ToLower();
5086
Assert.Equal(parameterStr?.ToLower(), str.ToLower());
5187
}
52-
88+
5389
[Theory]
5490
[InlineData("\\\"132\\\"")]
5591
public static void StringFormatParameterParsingShouldBeFail(string str)
5692
{
5793
Assert.Throws<ParseException<char>>(() => ParametersParser.StringFormatParameter.ParseOrThrow(str));
5894
}
59-
95+
6096
[Theory]
6197
[InlineData("$var$")]
6298
[InlineData("$var$.Trim")]
@@ -71,5 +107,4 @@ public static void ParameterParsingShouldBeSuccess(string str)
71107
var parameterStr = parameter.ToString()?.ToLower();
72108
Assert.Equal(parameterStr?.ToLower(), str.ToLower());
73109
}
74-
75110
}

src/SimpleStateMachine.StructuralSearch.Tests/PlaceholderParserTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public static class PlaceholderParserTests
88
[Theory]
99
[InlineData("($test$)", "(value )", "value ")]
1010
[InlineData("($test$ )", "(value )", "value")]
11+
[InlineData("($test$123)", "(value123)", "value")]
1112
[InlineData("($test$)", "(value (test))", "value (test)")]
1213
[InlineData("($test$)", "(value (test) )", "value (test) ")]
1314
public static void TemplateParsingShouldBeSuccess(string template, string source, string result)

src/SimpleStateMachine.StructuralSearch/Constant.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,22 @@ internal static class Constant
103103
/// <summary>
104104
/// Parenthesis chars: '(' and ')'
105105
/// </summary>
106-
public static readonly (char, char) Parenthesis = (LeftParenthesis, RightParenthesis);
106+
public static readonly (char, char) Parentheses = (LeftParenthesis, RightParenthesis);
107107

108108
/// <summary>
109109
/// Parenthesis chars: '[' and ']'
110110
/// </summary>
111-
public static readonly (char, char) SquareParenthesis = (LeftSquareParenthesis, RightSquareParenthesis);
111+
public static readonly (char, char) SquareParentheses = (LeftSquareParenthesis, RightSquareParenthesis);
112112

113113
/// <summary>
114114
/// Parenthesis chars: '{ and '}'
115115
/// </summary>
116-
public static readonly (char, char) CurlyParenthesis = (LeftCurlyParenthesis, RightCurlyParenthesis);
116+
public static readonly (char, char) CurlyParentheses = (LeftCurlyParenthesis, RightCurlyParenthesis);
117117

118118
/// <summary>
119119
/// Parenthesis chars: '(' and ')', '{ and '}', '{ and '}'
120120
/// </summary>
121-
public static readonly (char, char)[] AllParentheses = [Parenthesis, SquareParenthesis, CurlyParenthesis];
121+
public static readonly (char, char)[] AllParentheses = [Parentheses, SquareParentheses, CurlyParentheses];
122122

123123
/// <summary>
124124
/// Parenthesis chars: '(' and ')', '{ and '}', '{ and '}'

src/SimpleStateMachine.StructuralSearch/Extensions/ParserExtensions.cs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ public static Parser<TToken, IEnumerable<T>> AtLeastOnceUntilNot<TToken, T, U>(t
2222
? parser.AtLeastOnceUntil(Parser.Not(terminator))
2323
: throw new ArgumentNullException(nameof(parser));
2424

25-
public static Parser<TToken, IEnumerable<T>> UntilNot<TToken, T, U>(this Parser<TToken, T> parser,
26-
Parser<TToken, U> terminator)
27-
{
28-
ArgumentNullException.ThrowIfNull(parser);
29-
30-
return parser.Until(Parser.Not(terminator));
31-
}
32-
3325
public static bool TryParse(this Parser<char, string> parser, string value, out string? result)
3426
{
3527
ArgumentNullException.ThrowIfNull(parser);
@@ -46,11 +38,6 @@ public static Parser<TToken, T> ThenInvoke<TToken, T>(this Parser<TToken, T> par
4638
return x;
4739
});
4840

49-
public static Parser<TToken, bool> Contains<TToken, T>(this Parser<TToken, T> parser)
50-
=> parser != null
51-
? parser.Optional().Select(x => x.HasValue)
52-
: throw new ArgumentNullException(nameof(parser));
53-
5441
public static Parser<char, Match<T>> Match<T>(this Parser<char, T> parser)
5542
=> Parser.Map((oldPos, oldOffset, result, newPos, newOffset) =>
5643
{

src/SimpleStateMachine.StructuralSearch/Helper/EscapeHelper.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,34 @@ internal static class EscapeHelper
2020
//
2121
// public static string EscapeExclude(string str, Func<char, string> replaceRule, params char[] excluded)
2222
// => string.Join(string.Empty, str.Select(c => excluded.Contains(c) ? c.ToString() : replaceRule(c)));
23-
24-
public static string EscapeChars(string str, Func<char, string> replaceRule, IReadOnlySet<char> filter)
25-
=> string.Join(string.Empty, str.Select(c => filter.Contains(c) ? replaceRule(c) : c.ToString()));
23+
24+
internal static string Escape(ReadOnlySpan<char> input)
25+
=> Escape(input, Constant.CharsToEscape);
26+
27+
private static string Escape(ReadOnlySpan<char> input, IReadOnlySet<char> charsToEscape)
28+
{
29+
// Precalculate string size
30+
var extraLength = 0;
31+
foreach (var c in input)
32+
{
33+
if (charsToEscape.Contains(c))
34+
extraLength++;
35+
}
36+
37+
if (extraLength == 0)
38+
return new string(input);
39+
40+
Span<char> buffer = stackalloc char[input.Length + extraLength];
41+
var bufferIndex = 0;
42+
43+
foreach (var c in input)
44+
{
45+
if (charsToEscape.Contains(c))
46+
buffer[bufferIndex++] = Constant.BackSlash;
47+
48+
buffer[bufferIndex++] = c;
49+
}
50+
51+
return new string(buffer);
52+
}
2653
}

src/SimpleStateMachine.StructuralSearch/Parsers/Parsers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal static class Parsers
3636

3737
public static Parser<char, TResult> BetweenParentheses<T, TResult>(Parser<char, T> expr, Func<char, T, char, TResult> mapFunc)
3838
{
39-
var parsers = Constant.AllParentheses.Select(pair => Parser.Map(mapFunc, Parser.Char(pair.Item1), expr, Parser.Char(pair.Item1)));
39+
var parsers = Constant.AllParentheses.Select(pair => Parser.Map(mapFunc, Parser.Char(pair.Item1), expr, Parser.Char(pair.Item2)));
4040
return Parser.OneOf(parsers);
4141
}
4242

src/SimpleStateMachine.StructuralSearch/Parsers/PlaceholderParser.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ protected override Parser<char, string> BuildParser(Func<Parser<char, string>?>
5353
}).Try());
5454
}
5555

56-
var anyString = Grammar.StringLiteralChar
56+
// Was changed from StringLiteralChar
57+
var anyString = Grammar.NonLanguageSyntaxChar
5758
.AtLeastOnceAsStringUntil(lookahead);
5859

5960
var simpleString = Grammar.StringLiteral;

src/SimpleStateMachine.StructuralSearch/Rules/Parameters/PlaceholderPropertyParser.cs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,50 +9,44 @@ namespace SimpleStateMachine.StructuralSearch.Rules.Parameters;
99

1010
internal static class PlaceholderPropertyParser
1111
{
12-
private static Parser<char, Func<PlaceholderParameter, IRuleParameter>> PlaceholderSubProperty<TEnum>(PlaceholderProperty property, Func<PlaceholderParameter, TEnum, IRuleParameter> func)
12+
internal delegate IPlaceholderRelatedRuleParameter BuildPlaceholderRule(PlaceholderParameter parameter);
13+
14+
private static Parser<char, BuildPlaceholderRule> PlaceholderSubProperty<TEnum>(PlaceholderProperty property, Func<PlaceholderParameter, TEnum, IPlaceholderRelatedRuleParameter> func)
1315
where TEnum : struct, Enum
1416
=> Parsers.Parsers.EnumValue(property)
1517
.Then(CommonParser.Dote)
1618
.Then(Parser.CIEnum<TEnum>())
17-
.Select(enumValue => new Func<PlaceholderParameter, IRuleParameter>(placeholder => func(placeholder, enumValue)))
19+
.Select<BuildPlaceholderRule>(enumValue => placeholder => func(placeholder, enumValue))
1820
.Try();
1921

20-
private static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> File =
22+
private static readonly Parser<char, BuildPlaceholderRule> File =
2123
Parsers.Parsers.EnumValue(PlaceholderProperty.File)
2224
.Then(CommonParser.Dote)
2325
.Then(Grammar.Identifier)
24-
.Select(propertyName => new Func<PlaceholderParameter, IRuleParameter>(placeholder => new PlaceholderFileParameter(placeholder, propertyName)))
26+
.Select<BuildPlaceholderRule>(propertyName => placeholder => new PlaceholderFileParameter(placeholder, propertyName))
2527
.Try();
2628

27-
private static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> Column =
29+
private static readonly Parser<char, BuildPlaceholderRule> Column =
2830
PlaceholderSubProperty<ColumnProperty>(PlaceholderProperty.Column, (placeholder, property)
2931
=> new PlaceholderColumnParameter(placeholder, property));
3032

31-
private static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> Line =
33+
private static readonly Parser<char, BuildPlaceholderRule> Line =
3234
PlaceholderSubProperty<LineProperty>(PlaceholderProperty.Line, (placeholder, property)
3335
=> new PlaceholderLineParameter(placeholder, property));
3436

35-
private static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> Offset =
37+
private static readonly Parser<char, BuildPlaceholderRule> Offset =
3638
PlaceholderSubProperty<OffsetProperty>(PlaceholderProperty.Offset, (placeholder, property)
3739
=> new PlaceholderOffsetParameter(placeholder, property));
3840

39-
private static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> Lenght =
41+
private static readonly Parser<char, BuildPlaceholderRule> Lenght =
4042
Parsers.Parsers.EnumValue(PlaceholderProperty.Lenght)
41-
.Select(property => new Func<PlaceholderParameter, IRuleParameter>(placeholder => new PlaceholderLenghtParameter(placeholder, property)))
43+
.Select<BuildPlaceholderRule>(property => placeholder => new PlaceholderLenghtParameter(placeholder, property))
4244
.Try();
4345

44-
public static readonly Parser<char, Func<PlaceholderParameter, IRuleParameter>> PlaceholderPropertyParameter =
46+
internal static readonly Parser<char, BuildPlaceholderRule> PlaceholderPropertyParameter =
4547
CommonParser.Dote.Then(Parser.OneOf(Lenght, File, Column, Offset, Line))
4648
.Try()
4749
.Optional()
48-
.Select(property => new Func<PlaceholderParameter, IRuleParameter>(placeholder =>
49-
property.HasValue ? property.Value(placeholder) : placeholder));
50-
51-
// public static readonly Parser<char, IRuleParameter> PlaceholderPropertyParameter =
52-
// CommonTemplateParser.Placeholder.Before(CommonParser.Dote)
53-
// .Select(name => new PlaceholderParameter(name))
54-
// .Then(Parser.OneOf(Lenght, File, Column, Offset, Line),
55-
// (placeholder, func) => func(placeholder))
56-
// .TrimStart()
57-
// .Try();
50+
.Select<BuildPlaceholderRule>(property =>
51+
placeholder => property.HasValue ? property.Value(placeholder) : placeholder);
5852
}

src/SimpleStateMachine.StructuralSearch/Rules/Parameters/StringParameter.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,5 @@ public string GetValue(ref IParsingContext context)
1515
=> _value;
1616

1717
public override string ToString()
18-
{
19-
var value = EscapeHelper.EscapeChars(_value, c => $"{Constant.BackSlash}{c}", Constant.CharsToEscape);
20-
return $"{value}";
21-
}
18+
=> EscapeHelper.Escape(_value);
2219
}

0 commit comments

Comments
 (0)