#rule-engine #ruleengine #math-engine

expression_engine

纯Rust编写的表达式引擎

8个版本 (4个重大更新)

0.7.0 2023年12月17日
0.6.0 2023年8月18日
0.5.3 2023年3月25日
0.4.0 2023年3月25日
0.1.0 2023年3月19日

每月42次下载

Apache-2.0

110KB
3K SLoC

expression_engine

Build Status Latest Version License:Apache-2.0 codecov

简介

表达式引擎是一个纯Rust编写的库,它提供了一个用于编译和执行表达式的引擎。表达式表示可以执行并返回一个值的字符串(通常是,但不仅限于,布尔值、字符串和数字)。

表达式引擎旨在为用户提供一个引擎,可以使用配置执行复杂逻辑,而无需重新编译。它是构建业务规则引擎的良好替代品。

用法

调用引擎很简单。首先,定义您想要执行的表达式。其次,创建一个上下文来缓存预定义的内部函数和变量。然后,将变量和函数注册到上下文中。最后,使用表达式和上下文调用执行函数以获取执行结果。

use expression_engine::{create_context, execute, Value};
let input = "c = 5+3; c+=10+f; c";
let ctx = create_context!(
     "d" => 2,
     "b" => true,
     "f" => Arc::new(|params| Ok(Value::from(3)))
);
let ans = execute(input, ctx).unwrap();
assert_eq!(ans, Value::from(21))

特性

  • 易于使用(至少三行)
  • 丰富的类型和表达式(五种基本类型和七种表达式类型)
  • 支持预定义运算符
  • 支持函数和运算符注册
  • 支持运算符重定向

定义

表达式

Syntax
Expression(;Expression)*

Expression:
(
	LiteralExpression 
	| UnaryExpression
	| BinaryExpression
	| TernaryExpression
	| FunctionExpression
	| ReferenceExpression
	| ListExpression
	| MapExpression
	| NoneExpression

)

LiteralExpression

Syntax
LiteralExpression:
  (LITERAL_NUMBER|LITERAL_BOOL|LITERAL_STRING)

字面表达式是由单个标记组成的表达式,而不是标记序列。这里有三种字面表达式,分别是LITERAL_NUMBER、LITERAL_BOOL和LITERAL_STRING。

LITERAL_NUMBER

fn is_digit_char(ch: char) -> bool {
    return '0' <= ch && ch <= '9' || ch == '.' || ch == '-' || ch == 'e' || ch == 'E' || ch == '+';
}

连续字符,如上所示,将被解析为数字。

LITERAL_BOOL

falseFalse 将被解析为布尔值 false,而 trueTrue 将解码为布尔值 true

LITERAL_STRING

以 " 开始并以 " 结束或以 ' 开始并以 ' 结束的字符序列将被解码为 LITERAL_STRING。

UnaryExpression

Syntax
UnaryExpression:
  Operator Operand

Operand:
  Expression

一元表达式由操作数和一元运算符组成。所有一元运算符的优先级相同,具有从右到左的结合性。

UnaryOp 描述
! 逻辑否定运算符
not 逻辑否定运算符

BinaryExpression

Syntax
BinaryExpression:
  Lhs Operator Rhs

Lhs:
  Expresssion

Rhs:
  Expression

二元表达式包含两个操作数和一个运算符。所有二元运算符都具有从右到左的结合性,其优先级可能不同。支持的二元运算符如下所示

运算符 优先级 描述
|= 20
<<= 20
= 20
+= 20
^= 20
/= 20
&= 20
>>= 20
%= 20
-= 20
*= 20
|| 40
&& 50
> 60
>= 60
<= 60
!= 60
< 60
== 60
| 70
^ 80
& 90
>> 100
<< 100
+ 110
- 110
* 120
% 120
/ 120
beginWith 200
endWith 200

TernaryExpression

Syntax
TernaryExpression:
  Condition ? Lhs : Rhs

Condition:
  Expression

Lhs:
  Expression

Rhs:
  Expression

三元表达式由三个部分组成,分别是条件(Condition)、左侧(Lhs)和右侧(Rhs)。如果条件的结果为真,则返回左侧。否则返回右侧的结果。

FunctionExpression

Syntax
FunctionExpression:
  func(FunctionParams?)

FunctionParams:
  Expression(,Expression)*


函数表达式由参数组成的表达式序列,参数之间用逗号分隔。

引用表达式

引用表达式可以是变量或无参数的函数。

列表表达式

Syntax
ListExpression:
  [ListElements?]

ListElements:
  Expression(,Expression)*

列表表达式以开括号开始,以闭括号结束。它的参数是一系列表达式。

映射表达式

Syntax
MapExpression:
  {MapElements?}

MapElements:
  KeyElement:ValueElement(,KeyElement:ValueElement)*

KeyElement:
  Expression

ValueElement:
  Expression

映射表达式以开大括号开始,以闭大括号结束,其中包含一系列键值对,键和值都是表达式。

None表达式

Syntax
NoneExpression:
  None
  

None表达式的返回值是 None

依赖项

~0.7–1MB
~20K SLoC