这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
重点:规则引擎的设计与实现
难点:规则引擎的核心原理
1、认识规则引擎
规则简单易配置、易拓展。规则引擎是一种嵌入在应用服务中的组件,可以将业务决策从服务代码中分离出来,通过预定义的语义模块编写业务逻辑规则,执行时接受数据输入、解释业务规则和做出决策
优点
解决开发人员重复编码问题;业务决策与服务本身解耦,缩短开发路径
组成
数据输入、规则理解、规则执行
应用场景
风控对抗、活动策略运营、数据分析和清洗
2、编译原理基本概念
编译就是在不改变语义的条件下,源程序转换成另一种语言程序。又有解释型语言(如Java)和编译型语言(如C语言)
词法分析(Lexical Analysis)
把源代码字符串转换为词法单元(Token),它是一个确定的有限自动机DFA(Deterministic Finite Automaton)
语法分析(Syntax Analysis)
在词法分析的基础上,识别表达式语法结构,表达式的语法结构可以用抽象语法树(Abstract Syntax Tree)表示,我感觉和形式语言与自动机理论中的知识点差不多
抽象语法树
上下文无关语法(Context-Free Grammar)、递归下降算法(Recursive Descent Parsing)自顶向下构造语法树
上下文无关语法G
终结符集合T + 非终结符集合N + 产生式集合P + 起始符号S
巴科斯范式(BNF)
描述上下文无关理论的一种具体方法,通过BNF可以实现上下文无关文法的具体化、公式化、科学化,是实现代码解析的必要条件
递归下降算法(Recursive Descent Parsing)
按照语法规则匹配Token串
类型检查
类型综合,根据子表达式的类型构造出父表达式的类型;编译、执行时会检查
3、设计规则引擎
设计目标
支持特定语法、运算符、数据类型、优先级、预定义语法规则表达式的编译与运行
词法
设计词法分析的状态机
语法
优先级的表达;语法树结构,一元、二元运算符,括号
语法树执行与类型检查
预先定义每种操作符的执行逻辑,对抽象语法树进行后缀遍历;一个节点的左右节点完成执行后,校验左右子节点的类型是否符合对应操作符的类型检查预设规则
4、实现规则引擎
项目结构
编译(语法分析、构建语法树、词法分析);执行(抽象语法树定义、语法树执行、符号定义、类型定义、类型检查);词法单元(token类型、词法定义、token定义)
// token定义
type Token struct {
Kind Kind
Value interf/ace{}
Position int
}
var keywords = map[string]Kind{
"true": BoolLiteral,
"false": BoolLiteral,
}
// 词法分析
// 定义扫描器
type Scanner struct {
source []rune // 规则表达式字符串
position int // 遍历规则表达式过程中的位置
length int // 规则表达式字符串, 用于判断是否扫描结束
ch rune // position 位置对应的字符
}
// 定义语法分析器
type Parser struct {
tokens []token.Token
index int
tokenLength int
}
// 构建树
type Builder struct {
rootPlanner *precedence
parser *Parser
}
课后个人总结
我觉得这堂课的很多知识都来自编译原理,虽然我还没学习编译原理这门课程,但是我学习过形式语言与自动机理论,对词法分析、语法分析、语法树等知识都有所了解,再加上看了提前给的预习文档,所以听起来不是很难理解,也有自己的一些思考,收获还是很多的。后面在讲解简单规则引擎项目的核心时很快,我觉得还需要去看看,去熟悉熟悉。