Tiny Expression Evaluator (or TinyEE) is a simple expression language running on .NET's Dynamic Language Runtime.
Its main strengths are:
It's designed to be a power tool for domain experts to define rules and calculations that augment an existing system.
##Quick start The easiest way to use TinyEE is to call its static method Tee.Evaluate(expression) :
TEE.Evaluate("2^20") //returns 1048576
To use variables in your expression, pass in an object as the second parameter (dictionary and callback delegate are also supported).
TEE.Evaluate("z = (x+y)^3 = x^3 + 3*x^2*y + 3*x*y^2 + y^3", new{x=3,y=2,z=125})
//returns True
For cases when an expression is evaluated multiple times (such as in a plotting app), you can improve performance using cached compilation. The struct returned by Compiled() holds a reference to a compiled delegate, which can be invoked repeatedly without incurring any parsing overhead:
var expr = parsedExpr.Compile("x^3 + 3*x^2*y + 3*x*y^2 + y^3");//compiled
var result1 = expr.Evaluate(new{x=2,y=3});//result1 = 125
var result2 = expr.Evaluate(new{x=5,y=4});//result2 = 729
To get the list of variables in an expression, get a ParsedExpression:
var parsedExpr = TEE.Parse("z = x^3 + 3*x^2*y + 3*x*y^2 + y^3");
var variables = parsedExpr.Variables;//variables = [z,x,y]
##Syntax Reference The syntax borrows a lot from C#, JavaScript and Excel formula. When in doubt, there are 2 things to remember:
Literal data types
Type | Example | CLR type |
---|---|---|
Null | null | null |
String | "A Review of \"A Tale of Two Cities\" and \"Moby Dick\"" | System.String |
Boolean | True, False | System.Boolean |
Integer | -1234567890 | System.Int32 |
Decimal | +1234567890.555 | System.Double |
Integer range | 0..1048576 | IEnumerable<int> (lazily-evaluated) |
List | ["a string", 12, true, [0,1,2]] | Object[] |
Hash | { name:"Yoda", age:900, isMaster:true } | Dictionary<string,object> |
Basic Arithmetics
Type | Example |
---|---|
Addition | x + y |
Subtraction | x - y |
Multiplication | x * y |
Modulo | x % y |
Power | x ^ y |
Negation | -x |
Comparision
Type | Example |
---|---|
Equal | x = y |
Not Equal | x <> y |
Greater than | x > y |
Greater than or Equal | x >= y |
Less than | x < y |
Less than or Equal | x <= y |
Logical
Type | Example |
---|---|
AND | x and y |
OR | x or y |
NOT | not x |
Object
Type | Example | Note |
---|---|---|
Variable | x + $math.Max(y,z) | Variable names are case-sensitive, x and X are not the same. Their names must start with a character or the dollar sign ($). |
Method call | "anton".ToUpper() | |
Member Access | person.Name.Length | |
Indexer Access | table.Rows[0]["column-0"] | |
Global function call | SUM(x,y) | Note that global function names are allow to be case-insensitive, SUM() and sum() are the same. |
Grouping | (x + y) * z |
Branching
Type | Example | Note | |||
---|---|---|---|---|---|
Conditional | booleanVar ? "value-if-true" : "value-if-false" | ||||
Coalescing | nullableVar ?: "fallback-value" | This is similar to c#'s ?? operator or Javascript's use of ||. Unlike Javasript, however, this operator does not perform type conversion. |
Chaining and nesting Almost all expression can be chained or nested.
table01A.Rows[3]["col3"]
100>10 ? Sum(Max(1,2),Max(0,1),Max(-5,3)) : Sum(Min(-2,-3),Min(1,2))
x > y > z
condition1
? "value 1"
: condition2
? "value 2"
: "value 3"
Operator precedence and associativity
The following table shows all operators in order of precedence from highest to lowest:
Operator type | Operator |
---|---|
Primary | () f(x) x[y] x.y |
Arithmetics | - ^ * / % + - |
Comparison | = > < >= <= <> |
Boolean | not and or |
Branching | x?:y x?y:z |
All expressions are evaluated from left to right. The expression 2^2^2^2, for example, is evaluated as ((2^2)^2)^2 == 256 (same as in C# and Excel (but differs from Mathematical convention))
##Main APIs
Class | Function | Description |
---|---|---|
TinyEE.TEE | Evaluate(string):object | Parse, compile and evaluate an expression with no variables |
Evaluate(string,object):object | Parse, compile and evaluate an expression with a context object. Variables within the expression are resolved using the context's properties and fields. Both anonymous and named objects are supported. | |
Evaluate(string,Func<string,object>):object | Parse, compile and evaluate an expression with a context functor. The functor will be called when a variable needs to be resolved. | |
Parse(string):ParsedExpression | Parse an expression (no compilation or evaluation yet). The metadata from the returned object can be useful in building a dependency graph or in transforming to another language. | |
Compile(string):CompiledExpression | Parse and compile an expression (no evaluation yet). The returned struct simply wraps around a delegate to the compiled code and can be called over and over again. |
##Benchmark //TODO
##Credits TinyEE's parser and scanner are generated by Herre Kuijpers's excellent Tiny Parser Generator. All thanks go to him.
##License MS-PL
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。