[ 规则引擎设计与实现 | 青训营笔记 ]
这是我参与「第五届青训营」伴学笔记创作活动的第 6 天
零、前言:
记个笔记顺便(恰青豆还是有很多不完善也有可能对的地方还请大佬们指正
一、本堂课重点内容:
- 运用场景
- 核心原理
- youngEngine
二、详细知识点介绍:
6.1 认识规则引擎
-
嵌入在应用中的组件,将业务决策从应用中抽离出来,并使用预定义的语义编写决策。接受数据输入,解释业务规则,做出决策
-
组成
数据输入 -- 接受策略集
规则理解 -- 预定义语义
规则执行 -- 类型检查
-
应用场景
风控对抗
活动运营
数据分析及数据清洗
6.2 编译原理
-
词法分析 -- 把源代码字符串转化为词法单元
基于有限状态机 DFA 啥的(死去的记忆在攻击我,这个自己搜一下)
-
语法分析 -- 在词法分析的基础上,识别语法结构
基于抽象语法树(上下文无关语法)
-
类型检查
综合检查
- 根据子表达式构造父表达式的类型
运行/编译时检查
- 编译时提前声明
- 执行时根据传入的参数的类型,在执行过程中检查
6.3 设计一个规则引擎
-
设计目标
设计一个规则引擎,支持特定的词法、运算符、数据类型和优先级。并且支持基于以上预定义语法的规则表达式的编译和执行。
-
词法,运算符,类型,优先级
就按照 c语言的来吧
-
语法分析 -- 优先级
-
递归下降
- 语法树执行检查
语法树执行 -- 后续遍历
类型检查 -- 在节点左右子节点执行完成后分别校验类型是否符合预设
6.4 实现规则引擎
项目地址:简单的规则引擎 这个已经是web版的了但是只有处理运行规则的接口实现,新增删除等还没有写
项目结构:
.
├── README.md
├── compiler.go
├── compiler_test.go
├── compiler
│ ├── lexical.go
│ ├── parser.go # 语法分析
│ ├── parser_test.go
│ ├── planner.go # 构建语法树
│ ├── scanner.go # 词法分析
│ └── scanner_test.go
├── executor
│ ├── ast.go # 抽象语法树定义
│ ├── operator.go # 语法树执行
│ ├── svg.go # 可视化打印语法树 - 辅助工具
│ ├── symbol.go # 符号定义
│ ├── type.go # 类型定义
│ └── type_checker.go # 类型检查
└── token
├── kind.go # token类型
├── kind_test.go
├── lexer.go # 词法定义
└── token.go # token定义
运行:
docker-compose up (docker-compose 配置可看[ 项目记录 0 | 青训营笔记 ])
go run ./main.go
默认端口是 :8888 测试一下(官方文档response错了不知道改了没)
看一下代码
func Compiler(exp string) (*executor.Node, error) {
// 扫描语句
tokenScanner := compiler.NewScanner(exp)
// 词法分析
tokens, err := tokenScanner.Lexer()
if err != nil {
return nil, err
}
// 语法分析
parser := compiler.NewParser(tokens)
err = parser.ParseSyntax()
if err != nil {
return nil, err
}
// 优先级判断
astBuilder := compiler.NewBuilder(parser)
ast, err := astBuilder.Build()
if err != nil {
return nil, err
}
return ast, nil
}
6.5 课后作业
作业其实和这节课没什么大关系,瞎写了一下,喵喵喵lustresix/-young_engine_homework 青训营发的api有几个词打错了改了一下 api
三、总结
对于代码实现的部分我还要子再好好研究一下