diff --git a/src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs b/src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs
index e80b601..bcffd39 100644
--- a/src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs
+++ b/src/SimpleStateMachine.StructuralSearch.Sandbox/Program.cs
@@ -1,9 +1,13 @@
using System;
using System.Linq;
+using System.Text.Json;
using System.Text.RegularExpressions;
using Pidgin;
+using SimpleStateMachine.StructuralSearch.Configurations;
using SimpleStateMachine.StructuralSearch.Extensions;
using SimpleStateMachine.StructuralSearch.Rules;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
using static Pidgin.Parser;
using String = System.String;
diff --git a/src/SimpleStateMachine.StructuralSearch.Sandbox/SimpleStateMachine.StructuralSearch.Sandbox.csproj b/src/SimpleStateMachine.StructuralSearch.Sandbox/SimpleStateMachine.StructuralSearch.Sandbox.csproj
index 8ea8467..34cf2f5 100644
--- a/src/SimpleStateMachine.StructuralSearch.Sandbox/SimpleStateMachine.StructuralSearch.Sandbox.csproj
+++ b/src/SimpleStateMachine.StructuralSearch.Sandbox/SimpleStateMachine.StructuralSearch.Sandbox.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/FullConfig.yml b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/FullConfig.yml
new file mode 100644
index 0000000..58583c7
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/FullConfig.yml
@@ -0,0 +1,40 @@
+Configurations:
+ - FindTemplate: |-
+ if($var$ $sign$ null)
+ {
+ $var$ = $value$;
+ }
+ FindRules:
+ - $sign$ In ("Is", "==")
+ ReplaceTemplate: |-
+ $var$ ??= $value$;
+ ReplaceRules:
+
+
+
+ - FindTemplate: |-
+ if($condition$)
+ return $value1$;
+ else
+ return $value2$;
+ FindRules:
+ ReplaceTemplate: |-
+ return $condition$? $value1$ : $value2$;
+ ReplaceRules:
+
+
+
+ - FindTemplate: |-
+ if($value1$ $sign$ null)
+ {
+ $var$ = $value1$;
+ }
+ else
+ {
+ $var$ = $value2$;
+ }
+ FindRules:
+ - $sign$ In ("Is", "==")
+ ReplaceTemplate: |-
+ $var$ = $value1$ ?? $value2$;
+ ReplaceRules:
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/ShortConfig.yml b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/ShortConfig.yml
new file mode 100644
index 0000000..2c62d32
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFile/ShortConfig.yml
@@ -0,0 +1,36 @@
+Configurations:
+ - FindTemplate: |-
+ if($var$ $sign$ null)
+ {
+ $var$ = $value$;
+ }
+ FindRules:
+ - $sign$ In ("Is", "==")
+ ReplaceTemplate: |-
+ $var$ ??= $value$;
+
+
+
+ - FindTemplate: |-
+ if($condition$)
+ return $value1$;
+ else
+ return $value2$;
+ ReplaceTemplate: |-
+ return $condition$? $value1$ : $value2$;
+
+
+
+ - FindTemplate: |-
+ if($value1$ $sign$ null)
+ {
+ $var$ = $value1$;
+ }
+ else
+ {
+ $var$ = $value2$;
+ }
+ FindRules:
+ - $sign$ In ("Is", "==")
+ ReplaceTemplate: |-
+ $var$ = $value1$ ?? $value2$;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFileTests.cs b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFileTests.cs
new file mode 100644
index 0000000..3059f3e
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ConfigurationFileTests.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Json;
+using Pidgin;
+using SimpleStateMachine.StructuralSearch.Configurations;
+using Xunit;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
+namespace SimpleStateMachine.StructuralSearch.Tests
+{
+ public class ConfigurationFileTests
+ {
+ [Theory]
+ [InlineData("ConfigurationFile/ShortConfig.yml")]
+ [InlineData("ConfigurationFile/FullConfig.yml")]
+ public void ConfigurationFileParsingShouldBeSuccess(string filePath)
+ {
+ var yml = File.ReadAllText(filePath);
+ var deserializer = new DeserializerBuilder()
+ .WithNamingConvention(PascalCaseNamingConvention.Instance)
+ .Build();
+
+ var cfg = deserializer.Deserialize(yml);
+ }
+
+ // private ConfigurationsFile Mock()
+ // {
+ // var configurationFile = new ConfigurationsFile();
+ //
+ // }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindRule/IfValueIsNullFindRule.txt b/src/SimpleStateMachine.StructuralSearch.Tests/FindRule/IfValueIsNullFindRule.txt
new file mode 100644
index 0000000..7ef4c86
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/FindRule/IfValueIsNullFindRule.txt
@@ -0,0 +1 @@
+$sign$ In ("Is", "==")
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseFindTemplate.txt
similarity index 65%
rename from src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseTemplate.txt
rename to src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseFindTemplate.txt
index da77bcc..2e6d69a 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseTemplate.txt
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfElseFindTemplate.txt
@@ -1,4 +1,4 @@
-if($var1$ $sign$ $value1$)
+if($var1$ $sign$ $some1$)
{
$var$ = $value1$;
}
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfValueIsNullTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfValueIsNullFindTemplate.txt
similarity index 100%
rename from src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfValueIsNullTemplate.txt
rename to src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/IfValueIsNullFindTemplate.txt
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/NestedParenthesisedTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/NestedParenthesisedFindTemplate.txt
similarity index 100%
rename from src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/NestedParenthesisedTemplate.txt
rename to src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/NestedParenthesisedFindTemplate.txt
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/TernaryOperatorFindTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/TernaryOperatorFindTemplate.txt
new file mode 100644
index 0000000..808476d
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplate/TernaryOperatorFindTemplate.txt
@@ -0,0 +1,4 @@
+if($condition$)
+ return $value1$;
+else
+ return $value2$;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplateTests.cs b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplateTests.cs
index 48341c4..bc7e85f 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplateTests.cs
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/FindTemplateTests.cs
@@ -7,27 +7,30 @@ namespace SimpleStateMachine.StructuralSearch.Tests
public class FindTemplateTests
{
[Theory]
- [InlineData("FindTemplate/IfElseTemplate.txt")]
- [InlineData("FindTemplate/IfValueIsNullTemplate.txt")]
- [InlineData("FindTemplate/NestedParenthesisedTemplate.txt")]
+ [InlineData("FindTemplate/IfElseFindTemplate.txt")]
+ [InlineData("FindTemplate/IfValueIsNullFindTemplate.txt")]
+ [InlineData("FindTemplate/NestedParenthesisedFindTemplate.txt")]
+ [InlineData("FindTemplate/TernaryOperatorFindTemplate.txt")]
public void TemplateParsingShouldBeSuccess(string templatePath)
{
var findTemplate = File.ReadAllText(templatePath);
- var template = StructuralSearch.ParseFindTemplate(findTemplate);
+ var template = StructuralSearch.ParseFindTemplate(findTemplate, new ParsingContext());
Assert.NotNull(template);
}
[Theory]
- [InlineData("FindTemplate/IfElseTemplate.txt", "Source/IfElseSource.txt")]
- [InlineData("FindTemplate/IfValueIsNullTemplate.txt", "Source/IfValueIsNullSource.txt")]
- [InlineData("FindTemplate/NestedParenthesisedTemplate.txt", "Source/NestedParenthesisedSource.txt")]
+ [InlineData("FindTemplate/IfElseFindTemplate.txt", "Source/IfElseSource.txt")]
+ [InlineData("FindTemplate/IfValueIsNullFindTemplate.txt", "Source/IfValueIsNullSource.txt")]
+ [InlineData("FindTemplate/NestedParenthesisedFindTemplate.txt", "Source/NestedParenthesisedSource.txt")]
+ [InlineData("FindTemplate/TernaryOperatorFindTemplate.txt", "Source/TernaryOperatorSource.txt")]
public void SourceParsingBeFindTemplateShouldBeSuccess(string templatePath, string sourcePath)
{
var findTemplate = File.ReadAllText(templatePath);
var source = File.ReadAllText(sourcePath);
- var template = StructuralSearch.ParseFindTemplate(findTemplate);
+ var context = new ParsingContext();
+ var template = StructuralSearch.ParseFindTemplate(findTemplate, context);
var result = template.ParseOrThrow(source);
Assert.NotNull(template);
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/Mock/EmptyParsingContext.cs b/src/SimpleStateMachine.StructuralSearch.Tests/Mock/EmptyParsingContext.cs
new file mode 100644
index 0000000..bb60777
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/Mock/EmptyParsingContext.cs
@@ -0,0 +1,20 @@
+namespace SimpleStateMachine.StructuralSearch.Tests.Mock
+{
+ public class EmptyParsingContext : IParsingContext
+ {
+ public bool TryGetPlaceholder(string name, out string value)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void AddPlaceholder(string name, string value)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public string GetPlaceholder(string name)
+ {
+ return name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/PlaceholderParserTests.cs b/src/SimpleStateMachine.StructuralSearch.Tests/PlaceholderParserTests.cs
index cb4391b..891c18e 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/PlaceholderParserTests.cs
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/PlaceholderParserTests.cs
@@ -8,30 +8,32 @@ public class PlaceholderParserTests
[Fact]
public void FindTemplateShouldBeNotEmpty()
{
- Assert.Throws(() => StructuralSearch.ParseFindTemplate(string.Empty));
+ Assert.Throws(() => StructuralSearch.ParseFindTemplate(string.Empty, new ParsingContext()));
}
[Theory]
[InlineData("($test$)", "(value )", "value ")]
[InlineData("($test$ )", "(value )", "value")]
[InlineData("($test$)", "(value (test))", "value (test)")]
+ [InlineData("($test$)", "(value (test) )", "value (test) ")]
public void TemplateParsingShouldBeSuccess(string template, string source, string result)
{
- var templateParser = StructuralSearch.ParseFindTemplate(template);
+ var context = new ParsingContext();
+ var templateParser = StructuralSearch.ParseFindTemplate(template, context);
var res = templateParser.ParseOrThrow(source);
+ var value = context.GetPlaceholder("test");
- // var templateStr = File.ReadAllText(templatePath);
- // var template = StructuralSearch.ParseTemplate(templateStr);
- //
- // Assert.NotNull(template);
+ Assert.Equal(value, result);
}
[Theory]
[InlineData("$var$;$var2$;", "test;;;test;;;", "value ")]
public void TemplateParsingShouldBeSuccess2(string template, string source, string result)
{
- var templateParser = StructuralSearch.ParseFindTemplate(template);
+ var context = new ParsingContext();
+ var templateParser = StructuralSearch.ParseFindTemplate(template, context);
var res = templateParser.ParseOrThrow(source);
+
// var templateStr = File.ReadAllText(templatePath);
// var template = StructuralSearch.ParseTemplate(templateStr);
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfElseReplaceResult.txt b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfElseReplaceResult.txt
new file mode 100644
index 0000000..759b0d6
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfElseReplaceResult.txt
@@ -0,0 +1 @@
+temp == 125 ? 12 : 15;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfValueIsNullReplaceResult.txt b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfValueIsNullReplaceResult.txt
new file mode 100644
index 0000000..c479805
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/IfValueIsNullReplaceResult.txt
@@ -0,0 +1 @@
+temp ??= 12;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/TernaryOperatorReplaceResult.txt b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/TernaryOperatorReplaceResult.txt
new file mode 100644
index 0000000..14ef19f
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceResult/TernaryOperatorReplaceResult.txt
@@ -0,0 +1 @@
+return temp == 125? 12 : 15;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/IfElseReplaceTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/IfElseReplaceTemplate.txt
index 22b6f34..ae54928 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/IfElseReplaceTemplate.txt
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/IfElseReplaceTemplate.txt
@@ -1 +1 @@
-$var1$ $sign$ $value1$ ? $value1$ : $value2$;
\ No newline at end of file
+$var1$ $sign$ $value1$ ? $value2$ : $value3$;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/TernaryOperatorReplaceTemplate.txt b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/TernaryOperatorReplaceTemplate.txt
new file mode 100644
index 0000000..d8c217d
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplate/TernaryOperatorReplaceTemplate.txt
@@ -0,0 +1 @@
+return $condition$? $value1$ : $value2$;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplateTests.cs b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplateTests.cs
index 3a681a7..ca7f668 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplateTests.cs
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/ReplaceTemplateTests.cs
@@ -1,5 +1,7 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
+using SimpleStateMachine.StructuralSearch.Tests.Mock;
using Xunit;
namespace SimpleStateMachine.StructuralSearch.Tests
@@ -9,14 +11,44 @@ public class ReplaceTemplateTests
[Theory]
[InlineData("ReplaceTemplate/IfElseReplaceTemplate.txt", 14)]
[InlineData("ReplaceTemplate/IfValueIsNullReplaceTemplate.txt", 6)]
- public void TemplateParsingShouldBeSuccess(string templatePath, int stepsCount)
+ [InlineData("ReplaceTemplate/TernaryOperatorReplaceTemplate.txt", 11)]
+ public void TemplateParsingShouldHaveStepCount(string templatePath, int stepsCount)
{
var replaceTemplate = File.ReadAllText(templatePath);
var replaceBuilder = StructuralSearch.ParseReplaceTemplate(replaceTemplate);
- var result = replaceBuilder.Build();
-
+ var result = replaceBuilder.Build(new EmptyParsingContext());
+
Assert.NotNull(replaceTemplate);
Assert.Equal(replaceBuilder.Steps.Count(), stepsCount);
}
+
+ [Theory]
+ [InlineData("ReplaceTemplate/IfElseReplaceTemplate.txt", "ReplaceResult/IfElseReplaceResult.txt",
+ new[] { "var1", "sign", "value1", "value2", "value3" },
+ new[] { "temp", "==", "125", "12", "15" })]
+ [InlineData("ReplaceTemplate/IfValueIsNullReplaceTemplate.txt", "ReplaceResult/IfValueIsNullReplaceResult.txt",
+ new[] { "var", "value" },
+ new[] { "temp", "12" })]
+ [InlineData("ReplaceTemplate/TernaryOperatorReplaceTemplate.txt", "ReplaceResult/TernaryOperatorReplaceResult.txt",
+ new[] { "condition", "value1", "value2" },
+ new[] { "temp == 125", "12", "15" })]
+ public void ReplaceBuildShouldBeSuccess(string templatePath, string resultPath, string[] keys, string[] values)
+ {
+ var replaceTemplate = File.ReadAllText(templatePath);
+ var replaceResult = File.ReadAllText(resultPath);
+ var replaceBuilder = StructuralSearch.ParseReplaceTemplate(replaceTemplate);
+
+ var parsingContext = new ParsingContext();
+ for (int i = 0; i < keys.Length; i++)
+ {
+ parsingContext.AddPlaceholder(keys[i], values[i]);
+ }
+
+ var result = replaceBuilder.Build(parsingContext);
+
+ Assert.NotNull(replaceTemplate);
+ Assert.NotNull(replaceResult);
+ Assert.Equal(replaceResult, result);
+ }
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/SimpleStateMachine.StructuralSearch.Tests.csproj b/src/SimpleStateMachine.StructuralSearch.Tests/SimpleStateMachine.StructuralSearch.Tests.csproj
index 33c287e..16ce3e9 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/SimpleStateMachine.StructuralSearch.Tests.csproj
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/SimpleStateMachine.StructuralSearch.Tests.csproj
@@ -18,6 +18,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
@@ -34,6 +35,16 @@
Always
+
+ Always
+
+
+ Always
+
+
+
+
+
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/Source/IfElseSource.txt b/src/SimpleStateMachine.StructuralSearch.Tests/Source/IfElseSource.txt
index 659fc58..eca8909 100644
--- a/src/SimpleStateMachine.StructuralSearch.Tests/Source/IfElseSource.txt
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/Source/IfElseSource.txt
@@ -1,4 +1,4 @@
-if(temp = 125)
+if(temp == 125)
{
test = 12;
}
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/Source/TernaryOperatorSource.txt b/src/SimpleStateMachine.StructuralSearch.Tests/Source/TernaryOperatorSource.txt
new file mode 100644
index 0000000..a6fa515
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/Source/TernaryOperatorSource.txt
@@ -0,0 +1,4 @@
+if(temp == 125)
+ return 12;
+else
+ return 15;
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch.Tests/Test.cs b/src/SimpleStateMachine.StructuralSearch.Tests/Test.cs
new file mode 100644
index 0000000..cf92237
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch.Tests/Test.cs
@@ -0,0 +1,13 @@
+using YamlDotNet.Serialization;
+using System.Text.RegularExpressions;
+
+namespace SimpleStateMachine.StructuralSearch.Tests
+{
+ public class Test: INamingConvention
+ {
+ public string Apply(string value)
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Configurations/Configuration.cs b/src/SimpleStateMachine.StructuralSearch/Configurations/Configuration.cs
new file mode 100644
index 0000000..f44e82c
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/Configurations/Configuration.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace SimpleStateMachine.StructuralSearch.Configurations
+{
+ public class Configuration
+ {
+ public string FindTemplate { get; set; }
+
+ public List FindRules { get; set; }
+
+ public string ReplaceTemplate { get; set; }
+
+ public List ReplaceRules { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Configurations/ConfigurationsFile.cs b/src/SimpleStateMachine.StructuralSearch/Configurations/ConfigurationsFile.cs
new file mode 100644
index 0000000..b6afac7
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/Configurations/ConfigurationsFile.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace SimpleStateMachine.StructuralSearch.Configurations
+{
+ public class ConfigurationsFile
+ {
+ public List Configurations { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Extensions/SourceMatchManyParserExtensions.cs b/src/SimpleStateMachine.StructuralSearch/Extensions/SourceMatchManyParserExtensions.cs
index f8c8374..3e13a28 100644
--- a/src/SimpleStateMachine.StructuralSearch/Extensions/SourceMatchManyParserExtensions.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Extensions/SourceMatchManyParserExtensions.cs
@@ -9,13 +9,13 @@ public static class SourceMatchParserExtensions
// {
// return parsers.Select(x => Parsers.Series(x, getResult));
// }
- public static Parser> JoinResults(this Parser>> parsers)
+ public static Parser> JoinResults(this Parser>> parsers, IParsingContext context)
{
- return parsers.Select(x => Parsers.Series(x, y => string.Join(string.Empty, y)));
+ return parsers.Select(x => Parsers.Series(context, x, y => string.Join(string.Empty, y)));
}
- public static Parser> JoinResults(this Parser>> parsers)
+ public static Parser> JoinResults(this Parser>> parsers, IParsingContext context)
{
- return parsers.Select(x => Parsers.Series(x, y => y.Concatenate()));
+ return parsers.Select(x => Parsers.Series(context, x, y => y.Concatenate()));
}
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/IParsingContext.cs b/src/SimpleStateMachine.StructuralSearch/IParsingContext.cs
new file mode 100644
index 0000000..69e0ee0
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/IParsingContext.cs
@@ -0,0 +1,11 @@
+namespace SimpleStateMachine.StructuralSearch
+{
+ public interface IParsingContext
+ {
+ bool TryGetPlaceholder(string name, out string value);
+
+ void AddPlaceholder(string name, string value);
+
+ string GetPlaceholder(string name);
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Parsers/IContextDependent.cs b/src/SimpleStateMachine.StructuralSearch/Parsers/IContextDependent.cs
new file mode 100644
index 0000000..9ca7b95
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/Parsers/IContextDependent.cs
@@ -0,0 +1,7 @@
+namespace SimpleStateMachine.StructuralSearch
+{
+ public interface IContextDependent
+ {
+ void SetContext(IParsingContext context);
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Parsers/LookaheadParser.cs b/src/SimpleStateMachine.StructuralSearch/Parsers/LookaheadParser.cs
index 6ad42ac..de0854d 100644
--- a/src/SimpleStateMachine.StructuralSearch/Parsers/LookaheadParser.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Parsers/LookaheadParser.cs
@@ -1,25 +1,24 @@
-using System;
+using System.Diagnostics.CodeAnalysis;
using Pidgin;
namespace SimpleStateMachine.StructuralSearch
{
- public abstract class LookaheadParser : Parser
+ internal sealed class LookaheadParser : Parser
{
- private Parser _parser { get; set; }
+ private readonly Parser _parser;
- public abstract Parser BuildParser(Func?> next,
- Func?> nextNext);
-
- public void Lookahead(Func?> next, Func?> nextNext)
- {
- _parser = BuildParser(next, nextNext);
- }
-
- public override bool TryParse(ref ParseState state, ref PooledList> expected,
- out T result)
+ public LookaheadParser(Parser parser) => this._parser = parser;
+
+ public override bool TryParse(ref ParseState state, ref PooledList> expecteds, out T result)
{
- var res = _parser.TryParse(ref state, ref expected, out result);
- return res;
+ state.PushBookmark();
+ if (this._parser.TryParse(ref state, ref expecteds, out result))
+ {
+ state.Rewind();
+ return true;
+ }
+ state.PopBookmark();
+ return false;
}
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Parsers/ParserWithLookahead.cs b/src/SimpleStateMachine.StructuralSearch/Parsers/ParserWithLookahead.cs
new file mode 100644
index 0000000..187e6e9
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/Parsers/ParserWithLookahead.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using Pidgin;
+
+namespace SimpleStateMachine.StructuralSearch
+{
+ public abstract class ParserWithLookahead : Parser
+ {
+ private Func> _parser { get; set; }
+
+ public Func>> OnLookahead { get; set; }
+
+ public abstract Parser BuildParser(Func?> next,
+ Func?> nextNext);
+
+ public void Lookahead(Func?> next, Func?> nextNext)
+ {
+ // lazy initialization
+ _parser = () => BuildParser(next, nextNext);
+ }
+
+ public override bool TryParse(ref ParseState state, ref PooledList> expected,
+ out T result)
+ {
+ var res = _parser().TryParse(ref state, ref expected, out result);
+ return res;
+ }
+ }
+
+ public class LookaheadResult
+ {
+ public LookaheadResult(Parser parser, T result, int tokensCount)
+ {
+ Parser = parser;
+ Result = result;
+ TokensCount = tokensCount;
+ }
+
+ public T Result { get; }
+ public int TokensCount { get; }
+ public Parser Parser;
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Parsers/Parsers.cs b/src/SimpleStateMachine.StructuralSearch/Parsers/Parsers.cs
index a8acdd5..7428beb 100644
--- a/src/SimpleStateMachine.StructuralSearch/Parsers/Parsers.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Parsers/Parsers.cs
@@ -78,7 +78,7 @@ public static Parser> MapToMany(Parser Series(IEnumerable> parsers,
+ public static Parser Series(IParsingContext context, IEnumerable> parsers,
Func, R> func)
{
if (parsers == null)
@@ -86,7 +86,7 @@ public static Parser Series(IEnumerable(parsers, func);
+ return new SeriesParser(context, parsers, func);
}
public static Parser> BetweenChars(char left, char right,
@@ -134,5 +134,10 @@ public static Parser EnumValue(TEnum value, bool ignoreCase
{
return Parsers.String(value.ToString(), ignoreCase).AsEnum(ignoreCase);
}
+
+ public static Parser Lookahead(Parser parser) =>
+ parser != null ? (Parser)
+ new LookaheadParser(parser)
+ : throw new ArgumentNullException(nameof (parser));
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Parsers/PlaceholderParser.cs b/src/SimpleStateMachine.StructuralSearch/Parsers/PlaceholderParser.cs
index c1d1517..83a2d09 100644
--- a/src/SimpleStateMachine.StructuralSearch/Parsers/PlaceholderParser.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Parsers/PlaceholderParser.cs
@@ -1,56 +1,78 @@
using System;
+using System.Collections.Generic;
using Pidgin;
using SimpleStateMachine.StructuralSearch.Extensions;
namespace SimpleStateMachine.StructuralSearch
{
- public class PlaceholderParser : LookaheadParser
+ public class PlaceholderParser : ParserWithLookahead, IContextDependent
{
- public string Name { get; }
-
- public string Value { get; }
+ private IParsingContext _context;
+
public PlaceholderParser(string name)
{
Name = name;
}
-
+
+ public string Name { get; }
+
public override Parser BuildParser(Func> next,
Func> nextNext)
{
var _next = next();
var _nextNext = nextNext() ?? Parser.End.ThenReturn(string.Empty);
- var _lookahead = Parser.Lookahead(_next.Then(_nextNext).Try());
-
- Parser lookahead = new DebugParser(_lookahead);
+ var lookahead = Parsers.Lookahead(_next.Then(_nextNext, (s1, s2) =>
+ {
+ OnLookahead = () => new List>
+ {
+ new(_next, s1, s1.Length),
+ new(_nextNext, s2, s2.Length),
+ };
+ return Unit.Value;
+ }).Try());
+
var anyString = CommonTemplateParser.AnyCharWithPlshd
.AtLeastOnceAsStringUntil(lookahead);
-
- var simpleString = CommonTemplateParser.StringWithPlshd.Labelled("simpleString");
+
+ var simpleString = CommonTemplateParser.StringWithPlshd;
var token = Parser.OneOf(simpleString, CommonParser.WhiteSpaces).Try();
Parser term = null;
var parenthesised = Parsers.BetweenOneOfChars(x => Parsers.Stringc(x),
expr: Parser.Rec(() => term),
Constant.AllParenthesised).JoinToString();
-
+
term = Parser.OneOf(parenthesised, token).Many().JoinToString();
-
+
//parenthesised and tokens and whiteSpaces
var prdsAndTokens = Parser.OneOf(parenthesised, token)
.Until(lookahead)
.JoinToString()
.Try();
-
+
var parser = prdsAndTokens.Or(anyString);
return parser;
}
-
+
public override bool TryParse(ref ParseState state, ref PooledList> expected,
out string result)
{
- var res = base.TryParse(ref state, ref expected, out result);
+ bool res;
+
+ // No use look-ahead if placeholder is already defined
+ if (_context.TryGetPlaceholder(Name, out var value))
+ {
+ res = Parser.String(value).TryParse(ref state, ref expected, out result);
+ }
+ else
+ {
+ res = base.TryParse(ref state, ref expected, out result);
+ if (res)
+ _context.AddPlaceholder(Name, result);
+ }
+
return res;
- }
+ }
// internal Parser GetParser()
@@ -80,5 +102,9 @@ public override bool TryParse(ref ParseState state, ref PooledList: Parser
{
private readonly Func, R> _getResult;
- private readonly IEnumerable> parsers;
-
- public SeriesParser(IEnumerable> parsers, Func, R> getResult)
+ private readonly IEnumerable> _parsers;
+ private readonly IParsingContext _context;
+ private bool _initialized = false;
+ public SeriesParser(IParsingContext context, IEnumerable> parsers, Func, R> getResult)
{
- this._getResult = getResult;
- this.parsers = parsers;
+ _getResult = getResult;
+ _parsers = parsers;
+ _context = context;
}
-
+
public override bool TryParse(ref ParseState state, ref PooledList> expecteds, out R result)
{
+ Fill();
var results = new List();
- var count = parsers.Count();
+ var count = _parsers.Count();
- for (var i = count-1; i >= 0 ; i--)
+ for (int i = 0; i < _parsers.Count(); i++)
{
- if (parsers.ElementAt(i) is LookaheadParser lookaheadParser)
- {
- var number = i;
- lookaheadParser.Lookahead(() => parsers.ElementAtOrDefault(number + 1), () =>
- parsers.ElementAtOrDefault(number + 2));
- }
- }
-
- for (int i = 0; i < parsers.Count(); i++)
- {
- var parser = parsers.ElementAt(i);
+ var parser = _parsers.ElementAt(i);
if (!parser.TryParse(ref state, ref expecteds, out var _result))
{
result = default (R);
return false;
}
-
- Console.WriteLine($"R: {_result.ToString()}");
results.Add(_result);
+ SkipLookedParsers(parser, ref state);
+
+ void SkipLookedParsers(Parser parser, ref ParseState state)
+ {
+ if (parser is not ParserWithLookahead lookaheadParser || lookaheadParser is { OnLookahead: null })
+ return;
+
+ var lookaheadResults = lookaheadParser.OnLookahead.Invoke();
+
+ foreach (var result in lookaheadResults)
+ {
+ results.Add(result.Result);
+ state.Advance(result.TokensCount);
+ i++;
+ }
+
+ //recursion
+ foreach (var result in lookaheadResults)
+ {
+ SkipLookedParsers(result.Parser, ref state);
+ }
+ }
}
result = _getResult(results);
return true;
}
+
+
+ private void Fill()
+ {
+ if(_initialized)
+ return;
+
+ var count = _parsers.Count();
+
+ for (var i = count-1; i >= 0 ; i--)
+ {
+ var parser = _parsers.ElementAt(i);
+ if (parser is ParserWithLookahead lookaheadParser)
+ {
+ var number = i;
+ lookaheadParser.Lookahead(() => _parsers.ElementAtOrDefault(number + 1), () =>
+ _parsers.ElementAtOrDefault(number + 2));
+ }
+
+ if (parser is IContextDependent element)
+ {
+ element.SetContext(_context);
+ }
+ }
+
+ _initialized = true;
+ }
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/ParsingContext.cs b/src/SimpleStateMachine.StructuralSearch/ParsingContext.cs
new file mode 100644
index 0000000..0465cd5
--- /dev/null
+++ b/src/SimpleStateMachine.StructuralSearch/ParsingContext.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace SimpleStateMachine.StructuralSearch
+{
+ public class ParsingContext : IParsingContext
+ {
+ public Dictionary Placeholders { get; } = new();
+
+ public bool TryGetPlaceholder(string name, out string value)
+ {
+ return Placeholders.TryGetValue(name, out value);
+ }
+
+ public void AddPlaceholder(string name, string value)
+ {
+ Placeholders[name] = value;
+ }
+
+ public string GetPlaceholder(string name)
+ {
+ return Placeholders[name];
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Placeholder.cs b/src/SimpleStateMachine.StructuralSearch/Placeholder.cs
index 647b319..82d6405 100644
--- a/src/SimpleStateMachine.StructuralSearch/Placeholder.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Placeholder.cs
@@ -1,17 +1,17 @@
namespace SimpleStateMachine.StructuralSearch
{
- public class Placeholder
- {
- public static Placeholder Not => null;
- private PlaceholdersMaster _master;
- public Placeholder(PlaceholdersMaster master, string name, SourceMatch match)
- {
- _master = master;
- Name = name;
- Match = match;
- }
-
- public string Name { get; }
- public SourceMatch Match { get; }
- }
+ // public class Placeholder
+ // {
+ // public static Placeholder Not => null;
+ // private PlaceholdersMaster _master;
+ // public Placeholder(PlaceholdersMaster master, string name, SourceMatch match)
+ // {
+ // _master = master;
+ // Name = name;
+ // Match = match;
+ // }
+ //
+ // public string Name { get; }
+ // public SourceMatch Match { get; }
+ // }
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Rules/Parameters/PlaceholderParameter.cs b/src/SimpleStateMachine.StructuralSearch/Rules/Parameters/PlaceholderParameter.cs
index 2abf798..eea3068 100644
--- a/src/SimpleStateMachine.StructuralSearch/Rules/Parameters/PlaceholderParameter.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Rules/Parameters/PlaceholderParameter.cs
@@ -1,22 +1,29 @@
namespace SimpleStateMachine.StructuralSearch.Rules
{
- public class PlaceholderParameter : IRuleParameter
+ public class PlaceholderParameter : IRuleParameter, IContextDependent
{
- public string Name { get; }
+ private IParsingContext _context;
public PlaceholderParameter(string name)
{
Name = name;
}
+ public string Name { get; }
+
public string GetValue()
{
- throw new System.NotImplementedException();
+ return _context.GetPlaceholder(Name);
}
public override string ToString()
{
return $"{Constant.PlaceholderSeparator}{Name}{Constant.PlaceholderSeparator}";
- }
+ }
+
+ public void SetContext(IParsingContext context)
+ {
+ _context = context;
+ }
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/StructuralSearch/FindTemplateParser.cs b/src/SimpleStateMachine.StructuralSearch/StructuralSearch/FindTemplateParser.cs
index 3505eae..ae54714 100644
--- a/src/SimpleStateMachine.StructuralSearch/StructuralSearch/FindTemplateParser.cs
+++ b/src/SimpleStateMachine.StructuralSearch/StructuralSearch/FindTemplateParser.cs
@@ -18,8 +18,7 @@ static FindTemplateParser()
TemplateParser = Parser.OneOf(Parenthesised, Token)
.AtLeastOnce()
- .MergerMany()
- .JoinResults();
+ .MergerMany();
}
internal static readonly Parser>> Empty =
@@ -47,11 +46,11 @@ static FindTemplateParser()
internal static readonly Parser>> Parenthesised;
- private static readonly Parser> TemplateParser;
+ private static readonly Parser>> TemplateParser;
- internal static Parser ParseTemplate(string str)
+ internal static Parser ParseTemplate(string str, IParsingContext context)
{
- return TemplateParser.ParseOrThrow(str).AsMatch();
+ return TemplateParser.JoinResults(context).ParseOrThrow(str).AsMatch();
}
diff --git a/src/SimpleStateMachine.StructuralSearch/StructuralSearch/StructuralSearch.cs b/src/SimpleStateMachine.StructuralSearch/StructuralSearch/StructuralSearch.cs
index 8d3cafa..2febae4 100644
--- a/src/SimpleStateMachine.StructuralSearch/StructuralSearch/StructuralSearch.cs
+++ b/src/SimpleStateMachine.StructuralSearch/StructuralSearch/StructuralSearch.cs
@@ -6,8 +6,8 @@ namespace SimpleStateMachine.StructuralSearch
{
public static class StructuralSearch
{
- public static Parser ParseFindTemplate(string template)
- => FindTemplateParser.ParseTemplate(template);
+ public static Parser ParseFindTemplate(string template, IParsingContext context)
+ => FindTemplateParser.ParseTemplate(template, context);
public static IReplaceBuilder ParseReplaceTemplate(string template)
=> ReplaceTemplateParser.ParseTemplate(template);
diff --git a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/IReplaceBuilder.cs b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/IReplaceBuilder.cs
index 8fd6460..ab1aa34 100644
--- a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/IReplaceBuilder.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/IReplaceBuilder.cs
@@ -5,6 +5,6 @@ namespace SimpleStateMachine.StructuralSearch.ReplaceTemplate
public interface IReplaceBuilder
{
IEnumerable Steps { get; }
- string Build();
+ string Build(IParsingContext context);
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/PlaceholderReplace.cs b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/PlaceholderReplace.cs
index 43fa400..840d21a 100644
--- a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/PlaceholderReplace.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/PlaceholderReplace.cs
@@ -1,17 +1,24 @@
namespace SimpleStateMachine.StructuralSearch.ReplaceTemplate
{
- public class PlaceholderReplace:IReplaceStep
+ public class PlaceholderReplace : IReplaceStep, IContextDependent
{
- public string Name { get; }
+ private IParsingContext _context;
+ public string Name { get; }
+
public PlaceholderReplace(string name)
{
Name = name;
}
-
+
public string GetValue()
{
- return Name;
+ return _context.GetPlaceholder(Name);
+ }
+
+ public void SetContext(IParsingContext context)
+ {
+ _context = context;
}
}
}
\ No newline at end of file
diff --git a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/ReplaceBuilder.cs b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/ReplaceBuilder.cs
index 50f9a88..bf06d24 100644
--- a/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/ReplaceBuilder.cs
+++ b/src/SimpleStateMachine.StructuralSearch/Templates/ReplaceTemplate/ReplaceBuilder.cs
@@ -12,12 +12,17 @@ public ReplaceBuilder(IEnumerable steps)
Steps = steps;
}
- public string Build()
+ public string Build(IParsingContext context)
{
StringBuilder stringBuilder = new StringBuilder();
-
+
foreach (var step in Steps)
{
+ if (step is IContextDependent contextDependentStep)
+ {
+ contextDependentStep.SetContext(context);
+ }
+
stringBuilder.Append(step.GetValue());
}