锁定老帖子 主题:FEL(表达式语言)——7月30号更新
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | ||||||||||||
发表时间:2011-02-23
最后修改:2011-07-30
Fel使用说明
1:Fel简介 Fel是简单的、高效的、易扩展的开源项目,使用java开发的开源项目。 简单性:语法简单,与java表达式类似,支持中文变量和函数。其实现原理也非常简单,只要稍微有一些java基础就可以看懂源码。 高效性:不会比开源的脚本引擎慢。一些高级应用还可以大大高于其他脚本引擎。 易扩展:在执行表达式的主要环节(解析表达式、函数管理、操作符重载、引擎上下文、节点解释器)都有很高的可定制性。 Fel设计目标是面向最终用户和二次开发用户。它是功能灵活的、可以轻易掌控的和可定制的表达式语言。 2:快速入门 获取Fel 项目地址:http://code.google.com/p/fast-el/ 源代码:http://fast-el.googlecode.com/svn/trunk/ 安装部署 将fel-xx.jar、commons-lang-2.4.jar、antlr-3.2.jar加入classpath就可以使用。 3:组成结构 Fel的主要组成结构如下所示:
未完待续.... 项目地址:http://code.google.com/p/fast-el/ 演示代码所在类:com.greenpineyu.fel.examples.Example ------------------2010-03-08------------------------- 1:简单的例子 FelEngine fel = new FelEngineImpl(); Object result = fel.eval("5000*12+7500"); System.out.println(result); 输出: 67500 2:使用变量 FelEngine fel = new FelEngineImpl(); FelContext ctx = fel.getContext(); ctx.set("单价", "5000"); ctx.set("数量", new Integer(12)); ctx.set("运费", "7500"); Object result = fel.eval("单价*数量+运费"); System.out.println(result); 输出67500 3:调用对象的方法 FelEngine fel = new FelEngineImpl(); FelContext ctx = fel.getContext(); ctx.set("out", System.out); fel.eval("out.println('Hello Everybody')"); 输出: Hello Everybody ------------------2010-03-10------------------------- 4:变量命名空间 FelEngine fel = new FelEngineImpl(); String costStr = "成本"; FelContext rootContext = fel.getContext(); rootContext.set(costStr, "60000"); Object baseCost = fel.eval(costStr); System.out.println("基本费用:" + baseCost); MyContext myContext = new MyContext(); myContext.setParent(rootContext); myContext.set(costStr, new Integer(67500)); Object allCost = fel.eval(costStr, myContext); System.out.println("所有费用:" + allCost); 输出: 基本费用:60000 所有费用:67500 ------------------2010-03-14------------------------- 5:自定义解释器 FelEngine fel = new FelEngineImpl(); String costStr = "成本"; FelContext rootContext = fel.getContext(); rootContext.set(costStr, "60000"); FelNode node = fel.parse(costStr); //将变量解析成常量 node.setInterpreter(new ConstInterpreter(rootContext, node)); //下面这段代码执行速度非常高 node.eval(rootContext); ------------------2010-03-15------------------------- 6:数据表应用,计算求字段的乘积。 /* * 假设数据表中有两列,单价和数量。 * 现在需要通过表达式计算金额(表达式:单价*数量)。 * 通常的做法是通过context获取变量(单价、数量的值), * 在小数据量时,这种做法是很好的,但是大数据量时,性能就很差了。 * 如果使用自定义的解释器,会提高效率。 */ //数据表中单价列的记录 String[] price = new String[] { "2", "3", "4" }; //数据表中数量列的记录 String[] number = new String[] { "10.99", "20.99", "9.9" }; FelEngine fel = new FelEngineImpl(); String exp = "单价*数量"; FelNode node = fel.parse(exp); List<FelNode> children = node.getChildren(); MutableInt index = new MutableInt(0); //替换节点的解释器 for (Iterator iterator = children.iterator(); iterator.hasNext();) { FelNode child = (FelNode) iterator.next(); if ("单价".equals(child.getText())) { child.setInterpreter(new ColumnInterpreter(index, price)); } else if ("数量".equals(child.getText())) { child.setInterpreter(new ColumnInterpreter(index, number)); } } for (int i = 0; i < number.length; i++) { index.setValue(i); Object eval = node.eval(null); System.out.println("金额[" + price[i] + "*" + number[i] + "=" + eval + "]"); } 数据表中列解析器,用于解析字段变量(单价或数量) class ColumnInterpreter implements Interpreter { MutableInt index; String[] records; ColumnInterpreter(MutableInt index, String[] records) { this.index = index; this.records = records; } public Object interpret(FelContext context, FelNode node) { return records[index.intValue()]; } } 输出结果 金额[2*10.99=21.98] 金额[3*20.99=62.97] 金额[4*9.9=39.6] ------------------2010-07-30------------------------- 新版本做了一些简化,加入编译成java源码功能。效率大大提高,生成java源码的逻辑挺简单,方便修改和扩展。 支持新的表达式,如下所示: 1:"abc".substring(1)及所有的String类方法 2:对象.方法、对象.属性 代码刚刚写好,晚些时候加上文档。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-02-25
也不说下有什么特性之类
效率高、简单、易扩展的特点用什么体现呢? |
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-02-25
眼高手低 没啥意义
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-02-25
我现在用JSEL,你搞点例子看看啊!
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-02-25
请问你这个轮子是四方形的吗?
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-03-10
只能利用业余慢慢补充相关资料,并对代码进行持续更新。希望大家看一看,交流交流。
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-03-10
以前做过,用java解决不了对变量的值高速访问的问题,用c或者c++的指针很容易能提高这块的效率,用java最低限度也需要使用1次hash
|
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-03-10
最后修改:2011-03-10
ppgunjack 写道 以前做过,用java解决不了对变量的值高速访问的问题,用c或者c++的指针很容易能提高这块的效率,用java最低限度也需要使用1次hash
可以有不同的设计思路。例如说在传入“context”的时候不是一定要用Map,在表达式引擎内部也不是一定要用Map来维持binding。如果允许使用任意Object来做context,那就在表达式引擎内部根据profile对表达式做优化编译, 例如说编译这个表达式: bar + 1 生成类似这样的代码: if (arg instanceof Foo) { return ((Foo) arg).bar + 1 } else { return slowPath(); //... } 仅供参考 |
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-03-10
ppgunjack 写道 以前做过,用java解决不了对变量的值高速访问的问题,用c或者c++的指针很容易能提高这块的效率,用java最低限度也需要使用1次hash
如果需要调整访问变量,可以对变量节点进行預处理,以提高访问速度。代码如下所示: FelEngine fel = new FelEngineImpl(); String costStr = "成本"; FelContext rootContext = fel.getContext(); rootContext.set(costStr, "60000"); FelNode node = fel.parse(costStr); //将变量解析成常量 node.setInterpreter(new ConstInterpreter(rootContext, node)); //下面这段代码执行速度非常高 node.eval(rootContext); |
|||||||||||||
返回顶楼 | |||||||||||||
发表时间:2011-03-11
发布0.2版本。主要是代码重构和完善。
|
|||||||||||||
返回顶楼 | |||||||||||||