English (United States) | 中文
YACEP is a small and tiny csharp expression parser, can parse a valid single-line string to an abstract syntax tree. It also provides a simple compiler that can compile an abstract syntax tree to an IEvaluator
instance,
IEvaluator
instance can be executed as C# delegate.
Important
|
YACEP not supported multi-line expressions and will not be supported in the future. if you need multi-line expressions, my recommendation is IronLanguages |
"x+', '+y".Compile().EvaluateAs<string>(new { x = "hello", y = "world" });
// value is "hello, world"
"x + y".Compile().EvaluateAs<int>(new { x = 1, y = 2 });
// value is 3
var state = new
{
x = 7,
y = 43.0f,
z = new Dictionary<string, string>
{
["yacep"] = "yet another csharp expression parser",
["tupac-amaru"] = "was the last indigenous monarch (Sapa Inca) of the Neo-Inca State"
},
rand = new Func<object>(() => new Random().Next(1, 3)),
array = Enumerable.Range(1971, 1996 - 1971)
};
var expr = "x + y - z['yacep'].Length + max([1, 2, 3]) + (this.rand() > 2 ? 1971 : 1996) - len(array)";
var evaluator = expr.Compile();
var value = evaluator.EvaluateAs<decimal>(state);
-
I found a very interesting thing when using docker, Casbin. After reading the source code of Casbin, found that Casbin used a very simple DSL to solve a series of authorization problems. You can see it on Casbin's official website. There are many implementations of the language, but the work of the .net platform Casbin-Net has been in the WIP state for long time. After reading the source code of Casbin-Net, I found that the library did not continue to write down because it could not find a good expression parser. So I used a simplified hill climbing algorithm to write a simple implementation.
-
Out of the box - Zero-Configuration
-
Custom unary operator - support custom a string as an unary operator
-
Custom binary operator - support custom a string as a binary operator and set an order for it
-
Custom literal - support custom a literal as a value
-
Custom function - support custom function
-
Conditional expression - like ?: operator in C#
-
In expression - evaluates to true if it finds a variable in an array and false otherwise
-
Cross platform - build with netstandard2.0
-
Small and tiny - the core parser code is only 500+ lines
-
Low consumption - use ReadOnlySpan<T> Struct to read string
-
High Performance - good performance to access object’s public method, field, property value instance over using C# reflection. Benchmark report
-
Create a console application
mkdir yacep-demo cd yacep-demo dotnet new console
-
add TupacAmaru.Yacep
dotnet add package TupacAmaru.Yacep
-
update Program.cs
cat>Program.cs<<EOF using TupacAmaru.Yacep.Extensions; namespace yacep_demo { class Program { static void Main() => System.Console.WriteLine("x+', '+y".Compile().EvaluateAs<string>(new { x = "hello", y = "world" })); } } EOF
using TupacAmaru.Yacep.Extensions;
namespace yacep_demo
{
class Program
{
static void Main()
=> System.Console.WriteLine("x+', '+y".Compile().EvaluateAs<string>(new { x = "hello", y = "world" }));
}
}
-
Run
dotnet run
-
xUnit.net: a free, open source, community-focused unit testing tool for the .NET Framework
-
BenchmarkDotNet: Powerful .NET library for benchmarking
-
Coverlet: Cross platform code coverage for .NET Core
-
ReportGenerator: ReportGenerator converts coverage reports generated by OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo or Clover into human readable reports in various formats.