cch123 / blog_comment

comments of xargin.com
8 stars 0 forks source link

基于 Go 的内置 Parser 打造轻量级规则引擎 #97

Open cch123 opened 5 years ago

cch123 commented 5 years ago

http://xargin.com/rule-engine-on-go-parser/

rfyiamcool commented 5 years ago

好文

caibirdme commented 5 years ago

不用Go内置的Parser主要是因为它是和Go Language Spec绑定的,DSL主要是想创造新语法和新Token,你用内置Parser能够实现in_array(c, []int{1,2,3,4})但是实现不了 c in [1,2,3,4]。不过这个原理都是差不多,DSL讲究的就是一个“骚”,如果语法啥的都没变那不如直接写Go代码,codegen就行了,DSL没啥意义了

caibirdme commented 5 years ago

DSL要得是对特定场景的语言表达力,用Go Parser把同样的语法换一个地方写,那就真的是没事找事了

cch123 commented 5 years ago

@caibirdme ,实现得了。IDENT 可以随意扩充,in 后面的定义成业务规则就行了。 而且我文中已经说过了,再加上函数的扩展功能,大部分需求都可以实现,况且所谓规则引擎没有任何特殊场景一说,本质就是布尔表达式

caibirdme commented 5 years ago

不论怎么扩充,parse出来的都是Go spec的Token,IDENT只是token的一种,只能解析可以被用来声明成变量名的字符串。[1,2,3],这个解析出来显然是没有IDENT的,你怎么通过扩展IDENT实现这个的解析?a in b符合词法,但不符合文法,也就无从构建AST了。你把你的实例中的bool表达式a==1&&b==2换成a in b,就返回error了。加了新词法和新文法,就不可能用原来的编译器直接parse

cch123 commented 5 years ago

in_array(ident, f(1,2,3,4)) in(ident, f(1,2,3,4)) in(ident, PRESET_BUSINESS_ARR)

没必要抱着一个写法用到死,模仿sql的扩展方式什么都可以做

caibirdme commented 5 years ago

那这和

func in(a,b interface{}) bool {
}

in(ident, f(1,2,3,4))

有啥区别,干嘛还要用DSL…直接写Go代码就行了,DSL肯定得改语法啊

cch123 commented 5 years ago

规则是在数据库里的。。

ninghejun commented 4 years ago

@caibirdme 那这和

func in(a,b interface{}) bool {
}

in(ident, f(1,2,3,4))

有啥区别,干嘛还要用DSL…直接写Go代码就行了,DSL肯定得改语法啊

直接写go代码需要编译发布,很麻烦。 搞规则引擎是希望获得动态能力,通过修改DB或配置来灵活修改程序的行为。然后配合一个管理后台,可以让产品和运营通过web页面操作来控制程序逻辑。 至于语法规则,各种语言大同小异,新搞个DSL也没有简化多少,确实是没有必要搞新的DSL的,王垠也有类似观点。