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

101 阅读4分钟

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

认识规则引擎

定义

规则引擎是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

  • 使用规则引擎前的开发逻辑 image.png

  • 使用规则引擎后的开发逻辑

image.png

组成部分

image.png

应用

image.png

编译原理基本概念

编译就是 把某种语言的源程序,在不改变语义的条件下,转换成目标语言程序。

  • 如果源代码编译后在操作系统上运行,那目标代码就是汇编/机器代码。
  • 如果源代码编译后在虚拟机里执行,那目标代码是一种解释器可以理解的中间形式的代码

词法分析

词法分析(Lexical Analysis)是把源代码字符串转换成词法单元(Token)的过程。

如何识别Token? 确定的有限自动机DFA

确定的有限自动机就是一个状态机,它的状态数量是有限的。该状态机在任何一个状态,基于输入的字符,都能做出一个确定的状态转换

image.png

语法分析

语法分析(Syntax Analysis)是在词法分析的基础上,识别表达式的语法结构的过程。这个结构式一个树状结构,这棵树叫做抽象语法树

Token -> AST

抽象语法树

上下文无关语法(Context-Free Grammar)

语言句子无需考虑上下文,就可以判断正确性。可以使用巴克斯范式(BNF)表示。

a = 0;// 这是一个赋值语句,无论此语句前后是什么代码,此语句所代表的操作是确定的。
  • 使用原因
    • 便于编译器编写
    • 防止二义性
    • 汇编语言/机器语言是上下文无关的

上下文无关语法G:终结符集合T + 非终结符集合N + 产生式集合P + 起始符号S

  • G由T、N、S和P组成,由语法G推导出来的所有句子的集合称为G语言!

  • 终结符  组成串的基本符号。可以理解为词法分析器产生的token集合。比如 + Id ( ) 等

  • 非终结符  表示token的的集合的语法变量。比如 stmt varDecl 等等

  • 产生式:表示形式,S : AB ,就是说S的含义可以用语法AB进行表达。

    • 一个表示式可以由另外已知类型的表达式或符号推导产生
    • 内置符号:字面量标识符、运算符
    • 一个基础表达式可以由常量或标识符
    • 一个乘法表达式可以由基础表达式或者 乘法表达式 * 基础表达式 组成

image.png

巴科斯范式(BNF)

BNF是描述上下文无关理论的一种具体方法。

  • 本质上就是树形分解,分解成一棵抽象语法树
  • 每个产生式就是一个子树,在写编译器时,每个子树对应一个解析函数。
  • 叶子节点叫做 终结符,非叶子节点叫做 非终结符。
<expr> ::= <expr> + <term> | <expr> - <term> | <term>

<term> ::= <term> * <factor> | <term> / <factor> | <factor>

<factor> ::= ( <expr> ) | Num

递归下降算法 Recursive Descent Parsing

基本思路就是按照语法规则去匹配 Token 串,自顶而下构造语法树。在不断对Token进行语法下降过程中可能会遇到递归的情况。

image.png

  • 对于一个非终结符,要从左到右依次匹配其产生式中的每个项,包括非终结符和终结符。

  • 在匹配产生式右边的非终结符时,要下降一层,继续匹配该非终结符的产生式。

  • 如果一个语法规则有多个可选的产生式,那么只要有一个产生式匹配成功就行。如果一个产生式匹配不成功,那就回退回来,尝试另一个产生式。这种回退过程,叫做回溯(Backtracking)。

image.png

类型检查

类型检查指验证操作接收的是否为合适的类型数据以及赋值是否合乎类型要求。

类型检查分类分为静态检查动态检查

类型推导

类型综合:根据子表达式的类型构造出父表达式的类型。

例如,表达式A+B的类型是根据A和B的类型定义的 image.png

编译时检查 & 运行时检查

编译时:需要提前声明参数的类型,在构建语法树的过程中进行类型检查。

int1:int;str1:string

执行时:可以根据执行时的参数输入的类型,在执行过程中进行类型检查。

int1:110;str1:"300"