这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
规则引擎设计与实现
今日学习:
- 规则引擎
- 编译原理的部分
课程重难点
重点
- 规则引擎的设计 。明确设计目标、完成步骤拆解、完成各部分状态机的详细设计
- 规则引擎的实现。基于项目工程完成词法分析、语法分析、抽象语法树的执行功能
难点
-
规则引擎的核心原理(理论)。词法分析、语法分析、类型检查、语法树执行
这些部分涉及到了数据结构
定义
规则引擎是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。
解决开发人员重复编码的问题,提高维护性
组成部分
- 数据输入
接受外界的数据输入,支持预定义的语法编写的规则。比如"price > 500",接受业务的数据作为执行过程中的参数
- 规则理解
能够按照预先定义的语法,优先级等正确理解业务规则
- 规则执行
根据执行时候输入的参数对策略集中的规则进行解释和执行。同时进行检查
应用
风控对抗
活动策略运营
数据分析
编译原理
词法分析
把源代码字符串转化为词法单元的工程
price > 500 && (isNewUser || userLevel > 5)
如何识别token?
有限自动机
有限自动机就是一个状态机,状态数量是有限的。该状态机在任何一个状态,基于输入的字符,都能做一个确定的状态转换
抽象语法树
上下文无关语法
。。。。。
r:=a>b
.....
这是一个赋值语句,无论此语句的前后是什么代码,此语句所代表的操作是确定的。即给变量a赋值等于0
语法句子无需考虑上下文,可以判断正确性。可以使用巴斯克范式(BNF)来表达
BNF是描述上下文无关理论的一种具体方法,通过BNF可以实现上下文无关文法的具体化、公式化、科学化,是实现代码解析的必要条件。
exp:add;
add:add `+` mul | mul ; // 加法表达式
mul: mul '*' pri | pri //乘法表达式
pri: string | bool | number | identifer;// 基础表达式
产生式:一个表达式可以由另外已知类型的表达式或者符号推导产生
内置符号:标识符,运算符
一个基础表达式可由 常量或标识符
一个乘法表达式可以由 基础表达式 获取乘法表达式*基础表达式 组成
递归下降算法
不断的对Token进行语法展开
示例
过程就是从左到右不断遍历,然后根据找的词放在相应的位置,然后最后组装在一起
类型检查
类型综合
根据子表达式来构造父表达式的类型,例如,A+B的类型是根据A和B的类型定义的
编译时检查&运行时检查
类型检查可以在表达式的编译阶段,记载构造语法树的阶段;也可以发生在执行阶段
编译时:需要提前声明参数类型,在构造语法树的过程中进行类型检查
int 1: int ;str1:string
执行时:可以根据执行的参数输入的值类型,在执行过程中进行类型检查
int1: 108 ;str1:"22"
设计
目标
词法(合法token)
参数:字母数字下划线组成 eg:_ab2,user_name
布尔值:true,false
字符串:"22"
十进制int
十进制float
预定义运算符 +-
数据类型
字符串
布尔值
十进制int
十进制float
运算符
一元运算符 +-
二元
逻辑操作符
括号
优先级
常见的规则引擎
开源的代表是Drools,商业的代表是VisualRules ,iLog。
Java 开源的规则引擎有:Drools、URule、Easy Rules。使用最为广泛 Drools。
通过类型对规则引擎进行简单分类,一般有以下3类:
仓库
qimengxingyuan/young_engine: 简单的规则引擎 (github.com)
视频后期的演示仓库,容我拉下来好好看看,
代码感觉非常的规范但是有点复杂
个人理解
规则引擎就像一个系统,负责解析传入的规则,返回结果