这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
juejin.cn/post/719336… 上强度了……
重点内容概述
- 规则引擎是什么,如何完成一个简单的规则引擎
课前预习
规则引擎
规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。
我的理解:业务改变或更新意味着大量代码的改变,我们需要一个能简单地处理这种改变的应用 -> 规则引擎。感觉上可以实现低代码地更改业务结果
它是怎么做的:设定 rules,匹配 input data 推出结论
一个具体的例子:b 站的 Gengine
数据结构
编译原理
课上详细介绍
认识规则引擎
由来、优点、应用场景,了解组成和实现
由来、优点
和预习时的感受一样,大概就是抽象化条件
用以引入的例子:
规则引擎是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。
组成
- 数据输入
- 规则理解
- 规则执行
场景
- 风控对抗
- 与黑灰产对抗,策略要实时变化
- 活动策略运营
- 数据分析和清洗
- 对同一份数据根据需求定规则,方便快速
编译原理基本概念
介绍编译、词法分析、语法分析、抽象语法术、类型检查
编译本身就是个翻译的过程,将一种源代码翻译成另外一种:规则引擎本身就是在做这个事
规则引擎:
- 理解
- 词法分析:把源代码字符串转换为词法单元(token)
- 语法分析:在此基础上识别出表达式的语法结构
- 执行
- 抽象语法树:对一个表达式,有唯一的抽象语法书,是表达式抽象语法结构的树桩表示
- 输入输出
- 参数注入:使用输入的参数值来计算语法树标识符节点值的过程;代进去呗
- 类型检查:验证(某节点的子节点)数据类型是否合法
词法分析
hhh 熟悉啊,输入大模型前也要 tokenize
那么如何识别呢:有限自动机 finite-state automation
上一次接触还是学互联网协议
所以,词法阶段就是:基于状态机遍历表达式,输出 token 给下一阶段使用
语法分析
表达式的语法结构可以用树来表示,其每个节点(子树)是一个语法单元,这个单元的构成规则就叫“语法”。每个节点还可以有下级节点
语法树的生成需要我们自己去定义、去实现
抽象语法树
- 上下文无关语法
- 语言句子无需考虑上下文就可以判断正确性(不用看上下表达式就知道这句话要干嘛)。可以使用巴克斯范式(BNF)来表达
- 如
r := a>b mul : mul '*' pri | pri;mul 为基础表达式或一个 mul 乘以基础表达式,是在递归地去定义;我们还可以通过递归顺序定义优先级等等
- 递归下降算法 Recursive Descent Parsing
- 递归下降算法就是自顶向下构造语法树
- 不断的对 Token 进行语法展开(下降),展开过程中可能会遇到递归的情况。
- 详细
类型检查
类型综合
A+B 的类型是根据 A 和 B 的类型定义的
检查时间
- 编译时
- 需要提前声明参数的类型,在构建语法树的过程中检查
- 运行时
- 根据执行时的参数输入的值得类型,在执行过程中进行类型检查
设计一个规则引擎
词法
11 这种,向后预读一位
语法
- 语法树结构
- 一元运算符:左子树为空,右子树为右操作数
- 二元运算符:左子树为左操作数,右子树为右操作数
- 括号:左子树为空,右子树为内部表达式的 AST(意会一下(?))
执行
语法树执行
预先定义好每种操作符的执行逻辑,对抽象语法树进行后续遍历执行,即:
- 先执行左子树,得到左节点的值;
- 再执行右子树,得到有节点的值;
- 最后根据根节点的操作符执行得到根节点的值。
类型检查
- 我们设计为执行时检查,编译时检查工作量较大
- 检查方法:在一个节点的左右子节点执行完成后,分别校验左右子节点的类型是否符合对应操作符的类型检查预设规则
>符号要求左右子节点的值都存在且为int或float!符号要求左节点为空且右节点的值为 boo
规则引擎的实现
自己看项目啦