前言
这是我参与【第五届青训营】伴学笔记创作活动第六天,这节课的主要学习内容是理解规则引擎组成部分及应用场景,理解规则引擎的核心原理,及实践举例部分。
正文
认识规则引擎
- 定义:规则引擎是一种嵌入在应用程序的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接收数据输入,解释业务规则,并根据业务规则做出业务决策。
- 组成部分:1>数据输入:支持使用预编译的语义编写的规则作为策略集,接受业务的数据作为执行过程中的参数;2>规则理解:能够理解预先定义的词法,语法,优先级,运算符等正确理解业务规则所表达的语义;3>规则执行:根据执行输入的参数对策略集中的规则进行正确的解释和执行,同时对规则进行的规则和执行。同时对规则执行过程中的数据类型进行检查,确保执行结果的正确。
- 应用场景:风控对抗,活动策略运营,数据分析和清洗
编译原理基本概率
- 词法分析:把原代码字符串转换为词法单元的过程(有限自动机是一个状态机)
- 语法分析:在词法分析基础上,识别表达式语法结构的过程
- 抽象语法树:上下文无关语法:语言句子不需要考虑上下文,就可以判断正确性,可以使用巴科斯范式表达;
exp:add;
add:add'+'mul|mul; //加法表达式 a+b+c a+b*c
mul:mul‘*’pri|pri; //乘法表达式a*b*c
pri:string|bool|number|identifer;//基础表达式 wight|20|"abcde"
内置符号:字面量(string,bool,number)标识符,运算符
乘法表达式可以由基础表达式或者乘法表达式*基础表达式组成
mul:mul‘’pri|pri; == mul=>mul''pri;mul=>pri;
- 4. 递归下降法:
exp:log;
log:log('&&'|'||')cmp|cmp
cmp:cnp'>'add|add
add:add'+'mul|mul
mul:mul'+'pri|pri
pri:const|id(exp)
5.类型检查:类型综合:根据子表达式类型构造出父表达式类型。编译时检查&运行时检查:类型检查可以发生在表达式编译阶段,也可以发生在执行时阶段。
设计一个规则引擎
- 词法:参数:有字母数字下划线组成eg:_ab2,user_name;布尔值:true,false字符串:“abcd”,‘abcd’,
abcd;十进制int:1234;十进制float:123.5;预定义运算符:+- - 运算符:一元运算符:+-。二元运算符:+,-,*,/,%,>,<,>=,<=,==,|=。逻辑运算符:&&||!。括号:()。数据类型:字符串,布尔值,十进制int,十进制float
- 词法分析:设计词法分析的状态机
- 语法分析:
expr : logOr EOF ;
logOr : logOr '||' logAnd | logAnd ;
logAnd : logAnd ' &&' logNot | logNot ;
logNot :' ! ' logNot cmp ;
cmp : cmp '>' add | cmp '>=' add | cmp '<' add | cmp'<='add|cmp'=='add|cmp'!='add|add;
add : add '+'mul | add '-' mul | mul ;
mul : mul '*'pri | mul '/' pri | mul '%'pri|pri ;
pri : BocleanLiteral | IntegerLiteral | FlnatLiteral |Stringliteral |Identifier |'(' expr ')';
优先级表达:
type precedence struct {
valid5ymbols 【】Symbol //当前优先级支持的运算符类型
nextPrecedence * precedence //更高的优先级
planner planner //当前优先级的处理函数
语法树结构:一元运算符:左子树为空,右子树为右操作数 二元运算符:左子树为左操作数,右子树为右操作数括号:左子树为空,右子树为内部表达式的 AST 。
- 语法树执行和类型检查:预先定义好每种操作符的执行逻辑。 对抽象语法树进行后经温执行,即: 先执行左子树,得到左节点的值; 再执行右子树,得到有节点的值; 最后根据根节点的操作符执行得到根节点的值。
- 类型检查:检查时机:执行时检查; 检查方法:在一个节点的左右子节点执行完成后,分别校验左右子节点的类型是否符合对应操作符的类型检查预设规则; .">'符号要求左右子节点的值都存在且为 int 或 float ;‘!’符号要求左节点为空且右节点的值为 bool
个人总结
规则引擎的引入对于开发者进行维护和更新具有重要意义,减少了开发人员的工作量,使开发者可以更方便更快捷的更新数据。