Aviator 表达式求值引擎开源框架

简介

Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Avaitor呢?

Aviator的设计目标是轻量级高性能 ,相比于Groovy、JRuby的笨重,Aviator非常小,加上依赖包也才450K,不算依赖包的话只有70K;当然,Aviator的语法是受限的,它不是一门完整的语言,而只是语言的一小部分集合。

其次,Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都是通过解释的方式运行,而Aviator则是直接将表达式编译成Java字节码,交给JVM去执行。简单来说,Aviator的定位是介于Groovy这样的重量级脚本语言和IKExpression这样的轻量级表达式引擎之间。

特性

Aviator的特性

  • 支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、正则匹配操作符(=~)、三元表达式?: ,并且支持操作符的优先级和括号强制优先级,具体请看后面的操作符列表。

 

  • 支持函数调用和自定义函数

 

  • 支持正则表达式匹配,类似Ruby、Perl的匹配语法,并且支持类Ruby的$digit指向匹配分组。
  • 自动类型转换,当执行操作的时候,会自动判断操作数类型并做相应转换,无法转换即抛异常。
  • 支持传入变量,支持类似a.b.c的嵌套变量访问。
  • 性能优秀

Aviator的限制:

  • 没有if else、do while等语句,没有赋值语句,仅支持逻辑表达式、算术表达式、三元表达式和正则匹配。
  • 没有位运算符

整体结构

Aviator的结构非常简单,一个典型的求值器的结构

依赖包

commons-beanutilscommons-logging

使用手册

执行表达式

Aviator的使用都是集中通过com.googlecode.aviator.AviatorEvaluator这个入口类来处理,最简单的例子,执行一个计算1+2+3的表达式:

import com.googlecode.aviator.AviatorEvaluator; 
public class SimpleExample {  
   
public static void main(String[] args) {  
       
Long result = (Long) AviatorEvaluator.execute("1+2+3"); 
       
System.out.println(result); 
   
} 
}

细心的朋友肯定注意到结果是Long,而不是Integer。这是因为Aviator的数值类型仅支持Long和Double,任何整数都将转换成Long,任何浮点数都将转换为Double,包括用户传入的变量数值。这个例子的打印结果将是正确答案6。

使用变量

想让Aviator对你say hello吗?很简单,传入你的名字,让Aviator负责字符串的相加:

import com.googlecode.aviator.AviatorEvaluator; 
 
 
public class SayHello {  
   
public static void main(String[] args) {  
       
if (args.length < 1) {  
           
System.err.print("Usesage: Java SayHello yourname"); 
       
} 
       
String yourname = args[0]; 
       
Map<String, Object> env = new HashMap<String, Object>(); 
        env
.put("yourname", yourname); 
       
String result = (String) AviatorEvaluator.execute(" 'hello ' + yourname ", env); 
       
System.out.println(result); 
   
} 
}

上面的例子演示了怎么向表达式传入变量值,表达式中的yourname是一个变量,默认为null,通过传入Map<String,Object>的变量绑定环境,将yourname设置为你输入的名称。env的key是变量名,value是变量的值。

上面例子中的'hello '是一个Aviator的String,Aviator的String是任何用单引号或者双引号括起来的字符序列,String可以比较大小(基于unicode顺序),可以参与正则匹配,可以与任何对象相加,任何对象与String相加结果为String。String中也可以有转义字符,如/n、//、/'等。

AviatorEvaluator.execute(" 'a/"b' ");   //字符串 a'b 
AviatorEvaluator.execute(" /"a/'b/" ");  //字符串 a"b 
AviatorEvaluator.execute(" 'hello'+3 ");  //字符串 hello 3 
AviatorEvaluator.execute(" 'hello '+ unknow ");  //字符串 hello null

调用函数

Aviator支持函数调用,函数调用的风格类似lua,下面的例子获取字符串的长度:

AviatorEvaluator.execute("string.length('hello')");

string.length('hello')是一个函数调用,string.length是一个函数,'hello'是调用的参数。

再用string.substring来截取字符串:

AviatorEvaluator.execute("string.contains(/"test/",string.substring('hello',1,2))");

通过string.substring('hello',1,2)获取字符串'e',然后通过函数string.contains判断e是否在'test'中。可以看到,函数可以嵌套调用。

Aviator的内置函数列表请看后面。

自定义函数

Aviator除了内置的函数之外,还允许用户自定义函数,只要实现com.googlecode.aviator.runtime.type.AviatorFunction接口,并注册到AviatorEvaluator即可使用

public interface AviatorFunction {
    
   
/** 
     * Get the function name 
     *  
     * @return 
     */
 
   
public String getName(); 
 
 
   
/** 
     * call function 
     *  
     * @param env 
     *            Variable environment 
     * @param args 
     *            Function arguments 
     * @return 
     */
 
   
public AviatorObject call(Map<String, Object> env, AviatorObject... args); 
}

可以看一个例子,我们实现一个add函数来做数值的相加:

  import com.googlecode.aviator.runtime.function.FunctionUtils; 
 
import com.googlecode.aviator.runtime.type.AviatorDouble; 
 
import com.googlecode.aviator.runtime.type.AviatorFunction; 
 
import com.googlecode.aviator.runtime.type.AviatorObject; 
 
public class AddFunction implements AviatorFunction {  
 
       
public AviatorObject call(Map<String, Object> env, AviatorObject
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值