[02实践应用 - 规则引擎] 06 - 规则引擎设计与实现 | 青训营笔记

120 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第6天。今天的内容是关于规则引擎的,我认为这算是编译原理的一种工业使用。

1 认识规则引擎

规则引擎的定义:一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。

规则引擎的构成包括3部分:数据输入、规则理解和规则执行。

应用场景主要包括:风控对抗、活动运营策略、数据分析和清洗。

规则引擎的优点:代码复用性高,可以自己定义规则。功能上线效率可以提升至分钟级别。

2 编译原理基本概念

规则引擎编译原理的结构如下图所示。其中理解部分由词法分析和语法分析构成,对应的基本单元分别是字符串和表达式语法结构。执行部分通过抽象语法树实现,输入输出通过参数注入(验证流程正确)和类型检查(输出值的数据类型)实现。

graph TD
Start --> 理解 --> 执行 --> 输入输出 --> Stop

2.1 词法分析 Lexical Analysis

定义:把源代码字符转换为词法单元(Token)。

通过有限自动机(Finite-State Automation)识别 Token。有限自动机本质上就是一个状态机。

画出状态机即可视为词法分析的结束,此时得到了许多 Token。

2.2 语法分析 Syntax Analysis

定义:在词法分析的基础上,识别表达式的语法结构。

表达式的语法可以用抽象语法树来表示,每个节点(子树)代表一个语法单元。

2.3 抽象语法树 Abstract Syntax Tree

上下文无关语法 Context-free Grammar :句子无需考虑上下文即可判断正确性。可以使用巴克斯范式(BNF)表示。

产生式:由已知类型的表达式或符号推导构成的表达式。其中内置符号通常是语言已经定义好的字面量(bool, string 等)标识符、运算符,基础表达式可以由常量或标识符构成,

递归下降算法 Recursive Descent Parsing :用于自顶向下构造抽象语法树。

2.4 类型检查

类型综合:根据子表达式类型推导出父表达式类型。

类型检查按照执行时间区分可以分为编译时检查和运行时检查。编译时主要检查声明参数的类型,执行时按照实际输入的值检查。

3 设计一个规则引擎

3.1 设计目标

设计一个规则引擎,支持特定的词法、运算符、数据类型和优先级,并支持基于以上预定义语法的规则表达式的编译与执行。

列出需要的词法、数据类型、运算符、优先级。

3.2 词法和语法

需要画出词法分析向量机,定义优先级的表达和语法树的结构。

3.3 优先级与语法树

对抽象语法树进行后序遍历,检查类型。

4 总结

规则引擎可以视为代码自动解析逻辑的工具,可以通过输入特定格式的表达式实现复杂逻辑的自动分析,而不需要人工编写代码。使用规则引擎可以降低低效代码量,提高代码复用率。规则引擎可以视为编译原理课的一种工业应用场景,即有限状态自动机的应用。对于重复性高的场景,编写规则引擎的投入产出比较高,但是需要大量测试,因为人工分析语法结构很可能存在漏洞,需要进行大量的测试来保证每一个状态转移的逻辑都是正确的。