【实践】规则引擎的设计与实现 | 青训营笔记

122 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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
}

课后个人总结

我觉得这堂课的很多知识都来自编译原理,虽然我还没学习编译原理这门课程,但是我学习过形式语言与自动机理论,对词法分析、语法分析、语法树等知识都有所了解,再加上看了提前给的预习文档,所以听起来不是很难理解,也有自己的一些思考,收获还是很多的。后面在讲解简单规则引擎项目的核心时很快,我觉得还需要去看看,去熟悉熟悉。