[ 规则引擎设计与实现 | 青训营笔记 ]

506 阅读3分钟

[ 规则引擎设计与实现 | 青训营笔记 ]

这是我参与「第五届青训营」伴学笔记创作活动的第 6 天

零、前言:

记个笔记顺便(恰青豆还是有很多不完善也有可能对的地方还请大佬们指正

一、本堂课重点内容:

  • 运用场景
  • 核心原理
  • youngEngine

二、详细知识点介绍:

6.1 认识规则引擎

  • 嵌入在应用中的组件,将业务决策从应用中抽离出来,并使用预定义的语义编写决策。接受数据输入,解释业务规则,做出决策

2023-01-31-11-19-00-image.png

  • 组成

    数据输入 -- 接受策略集

    规则理解 -- 预定义语义

    规则执行 -- 类型检查

  • 应用场景

    风控对抗

    活动运营

    数据分析及数据清洗

6.2 编译原理

  • 词法分析 -- 把源代码字符串转化为词法单元

    基于有限状态机 DFA 啥的(死去的记忆在攻击我,这个自己搜一下)

  • 语法分析 -- 在词法分析的基础上,识别语法结构

    基于抽象语法树(上下文无关语法)

  • 类型检查

    综合检查

    • 根据子表达式构造父表达式的类型

    运行/编译时检查

    • 编译时提前声明
    • 执行时根据传入的参数的类型,在执行过程中检查

6.3 设计一个规则引擎

  • 设计目标

    设计一个规则引擎,支持特定的词法、运算符、数据类型和优先级。并且支持基于以上预定义语法的规则表达式的编译和执行。

    • 词法,运算符,类型,优先级

      就按照 c语言的来吧

    • 语法分析 -- 优先级

2023-01-31-12-21-19-image.png

    递归下降

-   语法树执行检查

    语法树执行 -- 后续遍历

    类型检查 -- 在节点左右子节点执行完成后分别校验类型是否符合预设

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错了不知道改了没)

2023-01-31-22-07-30-image.png

看一下代码

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

三、总结

对于代码实现的部分我还要子再好好研究一下