概要
关于gengine是干什么的,请参考B站新一代golang规则引擎的设计与实现 - 云+社区 - 腾讯云
本文主要通过两部分来解析gengine源码,一是介绍框架代码,理清楚该系统的架构;二是以跟随实际例子,看看在编译环节和执行环节分别做了哪些工作
gengine是基于antlr4来实现编译和执行的,之前也对该工具进行过介绍,可以参考Antlr4简介_zhanglehes的专栏-CSDN博客
框架代码
RuleBuilder.go文件
RuleBuilder.go 用于从字符串中解析出具体的语法树
type RuleBuilder struct {
Kc *base.KnowledgeContext
Dc *context.DataContext
buildLock sync.Mutex
}
它的核心方法
func (builder *RuleBuilder) BuildRuleFromString(ruleString string) error {
kc := base.NewKnowledgeContext()
in := antlr.NewInputStream(ruleString)
lexer := parser.NewgengineLexer(in) // 文本解析
lexerErrListener := iparser.NewGengineErrorListener()
lexer.AddErrorListener(lexerErrListener)
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
listener := iparser.NewGengineParserListener(kc) // listener是继承原生的listener,实现各回调函数的作用
psr := parser.NewgengineParser(stream)
psr.BuildParseTrees = true
//grammar listener
grammarErrListener := iparser.NewGengineErrorListener()
psr.AddErrorListener(grammarErrListener)
antlr.ParseTreeWalkerDefault.Walk(listener, psr.Primary()) // 遍历树,促发Accept函数的回调
return nil
}
BuildRuleFromString函数从字符串中解析规则,生成Kc,如果在语法解析中失败需要打印失败信息
将用户输入的字符串,解析为具体的语法时,需要这些定义好的节点来承接具体的数据。在执行具体的规则时,就是在语法树上的遍历递归,基于语法树遍历的顺序,来执行这些定义好的节点代码。
KnowledgeContext.go文件
KnowledgeContext.go 用于存储解析出来的规则,如果一次输入可以包含多条规则(rule),将它们分别进行存储。
type KnowledgeContext struct {
// ruleName - RuleEntity
RuleEntities map[string]*RuleEntity // 通过名称进行关联
SortRules []*RuleEntity // 按照优先级排序
SortRulesIndexMap map[string]int
}
DataContext.go 文件
DataContext.go 是用户向规则引擎中添加可用API的接口或结构体
type DataContext struct {
lockVars sync.Mutex // 保护规则文件中定义的变量
lockBase sync.Mutex // 保护base变量
base map[string]reflect.Value // 外部注入的变量,key为变

本文详细解析了Golang规则引擎gengine的架构、构建过程,包括如何从字符串解析语法树,以及执行阶段的函数调用和变量管理。重点介绍了框架代码、KnowledgeContext和DataContext的交互,以及规则执行的顺序和变量处理机制。

2971

被折叠的 条评论
为什么被折叠?



