SimpleParser 1.0.0-VER-01.56

This is a prerelease version of SimpleParser.
dotnet add package SimpleParser --version 1.0.0-VER-01.56                
NuGet\Install-Package SimpleParser -Version 1.0.0-VER-01.56                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SimpleParser" Version="1.0.0-VER-01.56" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SimpleParser --version 1.0.0-VER-01.56                
#r "nuget: SimpleParser, 1.0.0-VER-01.56"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SimpleParser as a Cake Addin
#addin nuget:?package=SimpleParser&version=1.0.0-VER-01.56&prerelease

// Install SimpleParser as a Cake Tool
#tool nuget:?package=SimpleParser&version=1.0.0-VER-01.56&prerelease                

SimpleParser

This project solves serveral problems

  • Parse expression to ast tree and the possibilty of calculating the result
  • Parse conditions 5+3 = 8 & 2*3 = 6
    • support =, !=, >, <, >=, ⇐, &, |
  • Use external variables in an expression
  • Use external functions in an expression
  • Parse view template $"string length = {{2+2}}", result is "string length = 4"
  • Serialize ast tree to json
  • Parse type as Guid, DateTime with timezone, Time span (05:30)
  • Types support, string, number, boolean, datetime, timespan, guid
  • Add support Array, Object, get item of array by index
  • Add IdentTabe, external variable holder
  • Add trinary operation 3+1 = 2*2 ? "OK" : "ERR"
  • Get value by index from identifier of any types
  • You can use functions with the same name and a different number of parameters
  • Add (if, each) statement for template string, see example
  • Add filter statement for template string, see example
  • Add AstAnalyzer, get info from ast tree, return (functions, constants, identifiers)
  • Parse time as 1d + 21h + 30m + 10s = '1.21:30:10'
  • Add internal function get each index ⇒ index(this.p), see example
  • Breaking changes, the expression in the template is wrapped in two brackets "result is {{2+3}}"
  • Support cyrillic name variables

How to use (Example)


internal static class InternalFuncs
{
    [FuncName("len")]
    public static ComputedResult Len(IFuncExecuteContext context, string str)
    {
        return new ComputedResult(str?.Length ?? default);
    }

    [FuncName("distination")]
    public static ComputedResult CalculateDistination(IFuncExecuteContext context, double x1, double y1, double x2, double y2)
    {
        var result = CalculateDistinationInternal(x1, y1, x2, y2);

        return new ComputedResult(result);
    }

    [FuncName("distination")]
    public static ComputedResult CalculateDistination(IFuncExecuteContext context, ComputedResult point1, ComputedResult point2)
    {
        var p1 = point1.Value;
        var p2 = point2.Value;

        var result = CalculateDistinationInternal(
            p1.GetProperty("x"),
            p1.GetProperty("y"),
            p2.GetProperty("x"),
            p2.GetProperty("y"));

        return new ComputedResult(result);
    }

    private static double CalculateDistinationInternal(double x1, double y1, double x2, double y2)
    {
        var a = Math.Pow(x2 - x1, 2);
        var b = Math.Pow(y2 - y1, 2);
            
        return Math.Sqrt(a + b);
    }
}

var identifier = new Dictionary<string, object>
{
    [x] = 5,
    [str] = "hello",
    ["point1"] = new Dictionary<string, object>
    {
        ["x"] = x1,
        ["y"] = y1,
    },
    ["point2"] = new Dictionary<string, object>
    {
        ["x"] = x2,
        ["y"] = y2,
    }
};

var funcTable = FuncTable.Create(typeof(InternalFuncs));
var identTable = IdentTable.Create(identifier);

var tree = LineParser.Parse("len(str)+x*2");

var result = AstCalculator.Calculate(tree, identTable, funcTable);

Assert.True(result.IsNumber());
Assert.Equal(15, result.ToNumber());

var treeCondition = LineParser.Parse("len(str) = 5");
result = AstCalculator.Calculate(treeCondition, identTable, funcTable);

Assert.True(result.IsBoolean());
Assert.True(result.ToBoolean());

tree = LineParser.Parse("distination(point1, point2)");
result = AstCalculator.Calculate(tree, identTabe, funcTable);
Assert.True(result.IsNumber());

tree = LineParser.Parse("distination(1, 2, 3, 4)");
result = AstCalculator.Calculate(tree, identTabe, funcTable);
Assert.True(result.IsNumber());

Type operations

Type left Type right Op Sample Result Description
string string + "hello" + " world" "hello world"
string string - "hello/ " - "/ " "hello" replace from the end "/" and " " (space)
string string * "hello" * "--" "--hello--"
string string / "hello one two" / "one " "hello two"
string number + "hello" + 5.1 "hello5.1"
string number - "hello5" - 5.1 hello remove from the end all of '5','.','1'
string number * "hello" * 5.1 5.1hello5.1
string number / "hello 5.1" / 5.1 "hello "
string boolean + "hello" + true "hellotrue"
string boolean - "hellotr" - true hello remove from the end of 't', 'r'
string boolean * "hello" * true "truehellotrue" add string to end and to start
string boolean / "true hello" / true " hello"
string datetime + "hello" + '31.12.2022' "hello31.12.2022" Depend on culture
string datetime - "hello" - '2022-12-31' NaN
string datetime * "hello" * '2022-12-31' "2022-12-31hello2022-12-31"
string datetime / "hello 2022-12-31" / '2022-12-31' "hello "
string timespan + "hello" + '12:35' "hello12:35"
string timespan - "hello12:35" - '12:35' hello
string timespan * "hello" * '12:35' "12:35hello12:35"
string timespan / "12:35hello" / '12:35' "hello" remove '12:35'
string guid + "hello" + '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' "hello6604ce0d-f880-4757-a8a4-2b5d5d7426a5"
string guid - "hello6f8" - '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' hello
string guid * "hello" * '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' "6604ce0d-f880-4757-a8a4-2b5d5d7426a5hello6604ce0d-f880-4757-a8a4-2b5d5d7426a5"
string guid / "hello6604ce0d-f880-4757-a8a4-2b5d5d7426a5" / '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' hello
number number + 2.2+5.3 7.5
number number - 2.2-5.3 -2.1
number number * 2*3 6
number number / 12/3 4
number string + 12+"hello" "12hello"
number string - 12-"hello" NaN
number string * 12*"hello" NaN
number string / 12/"hello" NaN
number boolean + 12+true 13
number boolean - 12-"hello" NaN
number boolean * 12*"hello" NaN
number boolean / 12/"hello" NaN
number datetime + 1+'10.12.2022' '10.12.2022 00:01:00 +03:00' Plus one minute
number datetime - 1-'10.12.2022' 'Nan
number datetime * 1*'10.12.2022' Nan
number datetime / 1/'10.12.2022' Nan
number timespan + 1+'12:35' '12:36:00' Plus one minute
number timespan - 1-'12:35' '-12:34:00' Minus one minute
number timespan * 1*'12:35' NaN
number timespan / 1/'12:35' NaN
number guid + 1+'6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
number guid - 1-'6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
number guid * 1*'6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
number guid / 1/'6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
boolean boolean + true+false 1
boolean boolean - true-false 1
boolean boolean * true*false 0
boolean boolean / false/true 0
boolean string + false + "hello" "falsehello"
boolean string - false - "hello" NaN
boolean string * false * "hello" NaN
boolean string / false / "hello" NaN
boolean number + true + 5 6
boolean number - true - 5 -4
boolean number * true * 5 5
boolean number / true / 5 0.20
boolean datetime + true + '10.12.2022' '10.12.2022 00:01:00'
boolean datetime - true - '10.12.2022' NaN
boolean datetime * true * '10.12.2022' NaN
boolean datetime / true / '10.12.2022' NaN
boolean timespan + true + '10:30' '10:31'
boolean timespan - true - '10:30' NaN
boolean timespan * true * '10:30' NaN
boolean timespan / true / '10:30' NaN
boolean guid + true + '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
boolean guid - true - '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
boolean guid * true * '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
boolean guid / true / '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
datetime datetime + '10.12.2022'+'10.12.2022' NaN
datetime datetime - '10.12.2022'+'10.12.2022' NaN
datetime datetime * '10.12.2022'+'10.12.2022' NaN
datetime datetime / '10.12.2022'+'10.12.2022' NaN
datetime number + '10.12.2022'+60*24 '11.12.2022'
datetime number - '10.12.2022'-60*24 '09.12.2022'
datetime number * '10.12.2022'*10 NaN
datetime number / '10.12.2022'/10 NaN
datetime timespan + '10.12.2022' + '23:00' '10.12.2022 23:00'
datetime timespan - '10.12.2022' - '23:00' '09.12.2022 01:00'
datetime timespan * '10.12.2022' * '23:00' NaN
datetime timespan / '10.12.2022' / '23:00' NaN
datetime guid + '10.12.2022' + '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
datetime guid - '10.12.2022' - '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
datetime guid * '10.12.2022' * '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
datetime guid / '10.12.2022' / '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
datetime boolean + '10.12.2022' + true '10.12.2022 00:01:00'
datetime boolean - '10.12.2022' - true '09.12.2022 23:59:00'
datetime boolean * '10.12.2022' * true NaN
datetime boolean / '10.12.2022' / true NaN
timespan timespan + '10:20' + '05:15' '15:35'
timespan timespan - '10:20' - '05:15' '05:05'
timespan timespan * '10:20' * '05:15' NaN
timespan timespan / '10:20' / '05:15' NaN
timespan number + '10:20' + 1 '10:21'
timespan number - '10:20' - 1 '10:19'
timespan number * '10:20' * 1 NaN
timespan number / '10:20' / 1 NaN
timespan boolean + '10:20' + true '10:21'
timespan boolean - '10:20' - true '10:19'
timespan boolean * '10:20' * true NaN
timespan boolean / '10:20' / true NaN
timespan datetime + '10:20' + '07.01.2023' '07.01.2023 10:20:00'
timespan datetime - '10:20' - '07.01.2023' NaN
timespan datetime * '10:20' * '07.01.2023' NaN
timespan datetime / '10:20' / '07.01.2023' NaN
timespan guid + '10:20' + '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
timespan guid - '10:20' - '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
timespan guid * '10:20' * '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
timespan guid / '10:20' / '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' NaN
timespan string + '10:20' + "hello" "10:20hello"
timespan string - '10:20' - "hello" NaN
timespan string * '10:20' * "hello" NaN
timespan string / '10:20' / "hello" NaN
guid string + '6604ce0d-f880-4757-a8a4-2b5d5d7426a5' + "hello" "6604ce0d-f880-4757-a8a4-2b5d5d7426a5hello"
guid string -,*,/ - NaN
guid timespan ALL - NaN
guid boolean ALL - NaN
guid datetime ALL - NaN
guid number ALL - NaN

Template string example


var departaments = new JsonArray
{
    new JsonObject
    {
        ["id"] = 12,
        ["name"] = "Cosmos"
    },
    new JsonObject
    {
        ["id"] = 4,
        ["name"] = "Buki"
    },
    new JsonObject
    {
        ["id"] = 9,
        ["name"] = "Durion"
    }
};

var persons = new JsonArray
{
    new JsonObject
    {
        ["id"] = 1,
        ["firstName"] = "Smith",
        ["lastName"] = "Ford",
        ["depCode"] = 12
    },
    new JsonObject
    {
        ["id"] = 2,
        ["firstName"] = "Ivan",
        ["lastName"] = "Petrov",
        ["depCode"] = 4
    },
    new JsonObject
    {
        ["id"] = 3,
        ["firstName"] = "Tim",
        ["lastName"] = "Cook",
        ["depCode"] = 9
    },
};

var source = @"$""Start
{#each deps dep filter this.dep.id>1 } 
    {index(this.dep)} Department: { this.dep.name}
    {#each persons p}
        {#if this.p.depCode=this.dep.id}
            {index(this.p)} Invite {this.p.id} with name: {this.p.firstName}
        {#else}
            {index(this.p)} go home: {this.p.lastName}
        {/if}
    {/each}
{/each}End""";

var tree = LineParser.Parse(source);

var identTable = IdentTable.Create(new JsonObject
{
    ["persons"] = persons,
    ["deps"] = departaments
});

var result = AstCalculator.Calculate(tree, identTable);

Console.WriteLine(result.ToString());
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on SimpleParser:

Package Downloads
JetPipe

Compile and run pipe async

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-VER-01.56 244 12/20/2023
1.0.0-VER-01.55 179 10/25/2023
1.0.0-VER-01.54 122 8/10/2023
1.0.0-VER-01.53 94 7/30/2023
1.0.0-VER-01.52 102 7/13/2023
1.0.0-VER-01.51 90 7/4/2023
1.0.0-VER-01.50 82 6/4/2023
1.0.0-VER-01.48 83 6/1/2023
1.0.0-VER-01.47 77 6/1/2023
1.0.0-VER-01.46 93 2/24/2023
1.0.0-VER-01.45 95 2/9/2023
1.0.0-VER-01.44 112 1/9/2023
1.0.0-VER-01.42 106 12/31/2022
1.0.0-VER-01.41 112 12/22/2022
1.0.0-VER-01.40 103 12/7/2022
1.0.0-VER-01.39 98 12/1/2022
1.0.0-VER-01.38 110 11/22/2022
1.0.0-VER-01.37 105 11/13/2022
1.0.0-VER-01.36 108 11/9/2022
1.0.0-VER-01.35 112 10/27/2022
1.0.0-VER-01.34 114 10/25/2022
1.0.0-VER-01.33 114 10/23/2022
1.0.0-VER-01.32 119 10/21/2022
1.0.0-VER-01.31 129 10/21/2022
1.0.0-VER-01.30 132 10/20/2022
1.0.0-VER-01.29 131 10/19/2022
1.0.0-VER-01.28 105 10/18/2022
1.0.0-VER-01.27 103 10/18/2022
1.0.0-VER-01.26 116 10/13/2022
1.0.0-VER-01.25 105 10/12/2022
1.0.0-VER-01.24 106 10/12/2022
1.0.0-VER-01.17 105 10/12/2022
1.0.0-VER-01.9 109 10/11/2022

Parse line to ast tree