规则表达式文法

规则表达式文法,第1张

概述1、背景 想写一个groovy规则表达式引擎。已经解决了groovy的脚本部分,但是在多脚本联合执行的时候,多个表达式的计算就变成一个难点了。 2、案例 例如,编写一个订购权限校验的引擎,即满足条件的用户才能对商品进行订购。 简单用伪代码的性质表示即: public boolean checkPermission(){ if(userId==121212L){ return 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、解决方案

毕竟要解决问题,想了很多方案。
①使用正则表达式,将表达式组里的表达式匹配出来,再进行执行。
后面发现,这个正则写法会很难,而且没有拓展性。

②编译文法
使用编译文法很容易就能够匹配出来,折腾了一个下午,终于能够顺利的把表达式组的内容全部解析出来。
1、环境安装

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 : [\r\n]+ ;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) ** todo\n");        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、拓展

上述还是有很多问题的,比如,无法传递参数,那么参数这个问题也要解决,很多规则校验都需要从外部传递参数进来的,这个后续再考虑

总结

以上是内存溢出为你收集整理的规则表达式文法全部内容,希望文章能够帮你解决规则表达式文法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1254379.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存