规则表达式文法
1、背景想写一个groovy规则表达式引擎。已经解决了groovy的脚本部分,但是在多脚本联合执行的时候,多个表达式的计算就变成一个难点了。 2、案例例如,编写一个订购权限校验的引擎,即满足条件的用户才能对商品进行订购。 public boolean checkPermission(){
if(userId==121212L){
return false;//不能订购
}
return true;//可以订购
}
那么可以编写groovy脚本 if(userId==121212L){
return false;//不能订购
}
return true;//可以订购
那么可以配置groovy脚本,key=checkPermission。 3、问题问题来了,一个规则配置上去很简单,执行也非常简单。但是如果存在多个表达的时候,就变得非常复杂了。例如,存在一个规则为: if((用户有购买权限 && 用户订购的时间不是周末) || 指定商品){
return true;
}
return false
这个时候就麻烦了,单独执行每个表达式很简单,但是如何执行(用户有购买权限 && 用户订购的时间不是周末) || 指定商品)这一串代码就非常复杂了。 4、解决方案毕竟要解决问题,想了很多方案。 ②编译文法 OS X
$ cd /usr/local/lib
$ sudo curl -O http://www.antlr.org/download/antlr-4.7-complete.jar
$ export CLASSPATH=".:/usr/local/lib/antlr-4.7-complete.jar:$CLASSPATH"
$ alias antlr4='java -jar /usr/local/lib/antlr-4.7-complete.jar'
$ alias grun='java org.antlr.v4.gui.TestRig'
2、文法编写 grammar Expr;
prog: (expr NEWLINE)* ;
expr: expr (' && ') expr | expr (' || ') expr | INT | '(' expr ')' ;
NEWLINE : [rn]+ ;
INT : [A-Za-z]+;
以上就是表达式组的规则 3、输出表达式 import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.Tree;
/** * Created by jianghuiwen on 17/5/8. */
public class MainTest {
public static void main(String[] args){
ANTLRInputStream in = new ANTLRInputStream("((jiang || hui) && test) ** todon");
ExprLexer lexer = new ExprLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExprParser parser = new ExprParser(tokens);
ExprParser.ProgContext ret = parser.prog();
for(int i = 0;i<ret.getChildCount();i++){
ParseTree parseTree = ret.getChild(i);
printTree(parseTree);
}
}
public static void printTree(ParseTree root){
if(root.getText().equals(" || ") || root.getText().equals("(")
|| root.getText().equals(")") ||root.getText().equals(" && ") ){
return;
}
if(root.getChildCount()>0){
for(int i=0;i<root.getChildCount();i++){
printTree(root.getChild(i));
}
}else{
System.out.println(root.getText());
}
}
}
4、输出结果 如上图所示,就把表达式组的表达式全部输出了。然后单独执行出结果,最后再做一个合并运算,就可以得出整个表达式组的值了。 5、拓展上述还是有很多问题的,比如,无法传递参数,那么参数这个问题也要解决,很多规则校验都需要从外部传递参数进来的,这个后续再考虑 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |