QLExpress java表达式计算开源项目

我要开发同款
匿名用户2010年07月21日
61阅读

技术信息

开源地址
https://github.com/killme2008/aviator/
授权协议
Apache 2.0

作品详情

 @authorqhlhl2010@gmail.com

 你想知道  aloveb=?吗,你想随意定义自己的操作符号吗?请使用QLExpress工具包

QLExpress是一个轻量级的类java语法规则引擎,作为一个嵌入式规则引擎在业务系统中使用。让业务规则定义简便而不失灵活。让业务人员就可以定义业务规则。支持标准的JAVA语法,还可以支持自定义操作符号、操作符号重载、函数定义、宏定义、数据延迟加载等。 

这个表达式相对别的计算工具,优点主要体现在:     A、不需要预先加载可能需要的所有属性值     B、用户可以根据业务需要自定义操作符号和函数     C、可以同步输出判断错误信息,有利于提高业务系统在规则判断等使用场景下的用户体验。减少业务系统相关的处理代码。          主要用途:一些业务规则的组合判断,同时需要输出相关的错误信息    执行的流程:  1、单词分解  2、语法分析  最简单Hello范例:    Strigexpress="10*10+1+2*3+5*2";   ExpressRuerruer=ewExpressRuer();   Objectresult=ruer.execute(express,ull,false,ull);   System.out.pritl("表达式计算:"+express+"="+result);  其它范例:   ExpressRuerruer=ewExpressRuer();  ruer.addOperator("love",ewLoveOperator("love"));  ruer.addOperatorWithAlias("属于","i","用户$1不在允许的范围");  ruer.addOperatorWithAlias("myad","ad","用户$1不在允许的范围");  ruer.addFuctio("累加",ewGroupOperator("累加"));  ruer.addFuctio("group",ewGroupOperator("group"));  ruer.addFuctioOfClassMethod("isVIP",BeaExample.class.getName(),    "isVIP",ewStrig[]{"Strig"},"$1不是VIP用户");  ruer.addFuctioOfClassMethod("取绝对值",Math.class.getName(),"abs",    ewStrig[]{"double"},ull);  ruer.addFuctioOfClassMethod("转换为大写",BeaExample.class.getName(),    "upper",ewStrig[]{"Strig"},ull); 

     在这个计算引擎里面,执行下述表达式结果:      Example0:System.out.pritl("ss")= ull      Example1:uioName=ewcom.ql.util.express.test.BeaExample("张三").uioName("李四")= 张三-李四      Example2:group(2,3,4)= 9      Example3:取绝对值(-5.0)= 5.0      Example4:max(2,3,4,10)= 10      Example5: max(3,2)+转换为大写("abc")= 3ABC      Example6: c=1000+2000= 3000      Example7:b=累加(1,2,3)+累加(4,5,6)= 21      Example8:三星卖家ad消保用户 = true      Example9:'a'love'b'love'c'love'd'= d{c{b{a}b}c}d      Example10: 10*10+1+2*3+5*2= 117      Example11: ((1+1)属于(4,3,5))adisVIP("玄难")= false        系统输出的错误提示信息:[用户2不在允许的范围, 玄难不是VIP用户]        表达式支持概述: 1、基本的java语法:   A、四则运算:10*10+1+2*3+5*2   B、boolea运算:3>2ad2>3    C、创建对象,对象方法调用,静态方法调用:ewcom.ql.util.express.test.BeaExample("张三").uioName("李四")    D、变量赋值:a=3+5    F、支持i,max,mi: (ai(1,2,4))ad(bi("abc","bcd","efg")) 2、提供表达式上下文,属性的值不需要在初始的时候全部加入,    而是在表达式计算的时候,需要什么信息才通过上下文接口获取    避免因为不知道计算的需求,而在上下文中把可能需要的数据都加入。    ruer.execute("三星卖家ad消保用户",errorList,true,expressCotext)    "三星卖家"和"消保用户"的属性是在需要的时候通过接口去获取。 3、可以将计算结果直接存储到上下文中供后续业务使用。例如:       ruer.execute("c=1000+2000",errorList,true,expressCotext);       则在expressCotext中会增加一个属性c=3000,也可以在expressCotext实现直接的数据库操作等。 4、可以将类和Sprig对象的方法映射为表达式计算中的别名,方便其他业务人员的立即和配置。例如:    将Math.abs()映射为"取绝对值"。则 "取绝对值(-5.0)"="5.0"    ruer.addFuctioOfClassMethod("取绝对值",Math.class.getName(),"abs",ewStrig[]{"double"},ull); 5、可以为已经存在的boolea运算操作符号设置别名,增加错误信息同步输出,在计算结果为false的时候,同时返回错误信息。例如:    ruer.addOperatorWithAlias("属于","i","用户$1不在允许的范围")。    用户自定义的函数同样也可以设置错误信息:例如:  ruer.addFuctioOfClassMethod("isOk",BeaExample.class.getName(),"isOk",ewStrig[]{"Strig"},"$1不是VIP用户");     则在调用ListerrorList=ewArrayList();    Objectresult=ruer.execute("((1+1)属于(4,3,5))adisOk("玄难")",errorList,true,ull);     执行结果result=false.同时在errorList中还会返回2个错误原因:      1、"用户2不在允许的范围",2、玄难不是VIP用户      这在业务系统需要进行规则计算,同时需要返回    6、可以自定义计算函数。例如:    自定一个操作函数group: classGroupOperatorextedsOperator{ publicGroupOperator(StrigaName){  this.ame=aName; } publicObjectexecuteIer(Object[]list)throwsExceptio{  Objectresult=ewIteger(0);  for(iti=0;i<list.legth;i++){   result=OperatorOfNumber.Add.execute(result,list[i]);  }  returresult; } }         然后增加到运算引擎:    ruer.addFuctio("累加",ewGroupOperator("累加")); ruer.addFuctio("group",ewGroupOperator("group"));         则执行:group(2,3,4) =9,累加(1,2,3)+累加(4,5,6)=21 7、可以自定义新的操作符号 。自定义的操作符号优先级设置为最高。例如:   自定一个操作函数love:classLoveOperatorextedsOperator{  publicLoveOperator(StrigaName){  this.ame=aName; } publicObjectexecuteIer(Object[]list)   throwsExceptio{  Strigop1=list[0].toStrig();  Strigop2=list[1].toStrig();  Strigresult=op2+"{"+op1+"}"+op2;    returresult; }}        然后增加到运算引擎:     ruer.addOperator("love",ewLoveOperator("love"));       则执行:'a'love'b'love'c'love'd'="d{c{b{a}b}c}d" 8、运算引擎在没有预编译的情况下,执行10万次 "10*10+1+2*3+5*2"耗时:3.187秒            ruer.execute("10*10+1+2*3+5*2",ull,false,ull);           在打开预编译缓存开关的情况下,执行10万次"10*10+1+2*3+5*2"耗时: 0.171秒            ruer.execute("10*10+1+2*3+5*2",ull,true,ull);                 运行引擎是线程安全的。在业务系统中实际使用过程中应该打开缓存预编译的开关,性能会更加。            可以调用clearExpressCache()清除缓存。          在开启开关的情况下,会缓存解析后的最后执行指令如下所示,          避免了字符串解析、词法分析、语法分析等步骤,简单对比一下,会提高30倍的速度: 1:LoadData10  2:LoadData10  3:OP:*OPNUMBER[2]  4:LoadData1  5:OP:+OPNUMBER[2]  6:LoadData2  7:LoadData3  8:OP:*OPNUMBER[2]  9:OP:+OPNUMBER[2]  10:LoadData5  11:LoadData2  12:OP:*OPNUMBER[2]  13:OP:+OPNUMBER[2]      9、这个表达式相对别的计算工具,有点主要体现在:     A、不需要预先加载可能需要的所有属性值     B、用户可以根据业务需要自定义操作符号和函数     C、可以同步输出判断错误信息,有利于提高业务系统在规则判断等使用场景下的用户体验。减少业务系统相关的处理代码。  10、后续可以进一步优化的地方:     A、现有的单词拆解、词法分析、语法分析都是自己写的山寨版,可以利用其他成熟的开源工具。     B、优化具体的操作指令,提高单个操作符号的运行效率     C、经过简单的扩展支持自定义代码片段的运行。   

功能介绍

@author qhlhl2010@gmail.com 你想知道 a love b = ? 吗 ,你想随意定义自己的操作符号吗 ? 请使用 QLExpress工具包 QLExpress 是一个轻...

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论