正式发布表达式计算引擎WfcExp V0.9(附源码)

        前几天已经已把框架做好了,见http://andywu.cnblogs.com/archive/2005/11/25/284772.html,这两天也就是补充完善一下。之所以是0.9版,是因为这个版本已经可以完成表达式中常用的所有功能,但容错处理还不是很好,也就是说可以正确地执行正确的表达式,但错误的表达式将产生未知的结果。

这个版本基本上可以完成目前表达式所能做的绝大部分功能了,如果想扩展可以自己修改源代码,或者把你需要的功能告诉我,我有时间会不断完善这个引擎的。

源代码是Public的,向Antlr学习。当然,如果你采用了我的组件,我很希望能让我知道或有所建议,我会觉得很欣慰。

表达式引擎在源码级可以任意扩展。其中IOperator接口很重要,该接口定义了表达式引擎的运算操作,只需实现IOperator接口,即可实现自定义的运算操作。源代码中的WfcExpOperator类即实现了IOperator接口,如果要实现自己的功能,可以设计一个自定义的实现IOperator接口的类即可。

以下是表达式支持的运算符,按优先级从高到低排列

类别 运算符
基本
x.y   x.f(x)  f(x)  a[x]  
一元
+  -  ! 
乘法
*  / 
加法
+  -
关系和类型检测
<  >  <=  >=  like
相等  =    != 
条件 AND
&&
条件 OR
||

注:
① !,&&,||可以用not,and,or代替,!=可用<>代替
② like 运算符支持正则表达式匹配

运算符的操作是通过IOperator接口的相应方法实现,一开始设计时为每个运算符对应一个接口方法,后来觉得太麻烦,就改为统一调用IOperator.Execute(string opname,ArrayList operands),条件运算和关系运算均采用Execute方法,但以前实现的运算方法我就没去动了,^_^。


支持的常量为INT,DOUBLE,DATETIME,STRING
a). 其中STRING常量为成对单引号或双引号,如果在字符串中有引号则加斜杠\,比如 ' I\'m happy '," I'm happy",' It is said "hello" ',"It is said \"hello\" "都是合法的字符串常量。
b). DATETIME常量由成对的#组成,比如:#2005-11-05 22:19# ,分隔符可用 - . / ,年份可以是2位,简言之只要是Convert.ToDateTime(string dt)支持的格式均可。

支持任意类型的变量,通过实现IOperator.GetExternalVariable自定义,可参考WfcExpOperator的代码

支持函数,引擎内部函数或外部函数(外部函数的调用是通过委托实现的,通过IOperator.CallFunction实现 。

支持对象的公共成员,包括方法(method)、属性(property)、索引器和字段(field) ,通过IOperator.CallMethod, CallProperty实现,运用了Reflection,性能上没做大量运算的测试。对于对象的公共方法,也可以通过设置外部函数来调用,设置外部函数是通过委托调用的,在性能上应该更好一些。直接用Reflection的确是调用对象公共成员最方便的方法。

演示项目并没有什么大的变化,可自己试验。Enjoy it。

点这里下载WfcExp表达式组件V0.9源代码

updated at 2007.09.27
最近一个园子里的朋友打电话给我, 说起正研究这一类的技术, 想看一下.g文件作为参考. 这很早的文章也翻得到, 挺佩服他的. 当初作这个也只是兴趣而为, 回来可是一通好找啊, 总算还在. 就补一下.g文件, 大家共勉.

点这里下载.g语法文件

posted @ 2005-11-28 23:00 andy.wu 阅读(2002) 评论(13)  编辑 收藏 网摘

  回复  引用  查看    
#1楼2005-11-29 11:11 | jhtchina      
学习,这里的高人好多呀
  回复  引用  查看    
#2楼2005-11-29 23:13 | C# hack      
高兴
  回复  引用  查看    
#3楼2005-12-10 13:01 | IT      
条件表达式可以吗???
  回复  引用  查看    
#4楼2005-12-10 13:02 | IT      

if(a==1)
return 0;
else
return 1;

或if(a==1) 0 else 1;
我觉得这样的表达式也可以的哦

  回复  引用  查看    
#5楼[楼主]2005-12-11 22:12 | andy.wu      
to IT:
可以通过自定义函数来实现,比如IIF(condition,exp1,exp2).

目前还没有想好怎么处理 ?:这个操作符

  回复  引用  查看    
#6楼2006-01-30 03:18 | C# hack      
为什么不把antlr .g文件放在源码里面?这样你提供的源码参考价值大减!

class CalcParser extends Parser;

expr returns [double value = 0.0]
{double x;}
: value=mexpr
( PLUS x=mexpr {value += x;}
| MINUS x=mexpr {value -= x;}
)*
;

mexpr returns [double value=0.0]
{double x;}
: value=atom
( MULTI x=atom {value *= x;}
| DIVIDE x=atom {value /= x;}
)*
;

atom returns [double value=0.0]
{double x;}
: d:DOUBLE {value=Double.parseDouble(d.getText());}
| LPAREN value=expr RPAREN
| PLUS x=atom {value = x;}
| MINUS x=atom {value = -x;}
;

class CalcLexer extends Lexer;

LPAREN : '(' ;
RPAREN : ')' ;
PLUS : '+' ;
MINUS : '-' ;
MULTI : '*' ;
DIVIDE : '/' ;
WS : (' ' | '\t' | '\n' | '\r') {$setType(Token.SKIP);} ;
DOUBLE : ('0'..'9')+ ('.' ('0'..'9')+)? ;

  回复  引用    
#7楼2007-05-08 18:42 | 阿晓[未注册用户]
取整运算怎样实现?
  回复  引用  查看    
#8楼[楼主]2007-05-09 11:17 | andy.wu      
@ 阿晓
这个工程好久没动了,都不太清楚了。

印象中,只需要定义一个函数就可以了。你可以看一下函数定义的例子。

  回复  引用    
#9楼2007-05-12 21:21 | 阿晓[未注册用户]
@andy.wu
定义函数还是比较简单的,非常感谢。异常处理还不大好,直接抛出的异常会使程序直接死掉。另外,能否提供使用的语法的 .g 文件?

  回复  引用    
#10楼2007-11-29 19:53 | xiaozhunic[未注册用户]
高手啊!
请问一下,如何实现表达式,比如if语句,while语句的执行。
另外,g文件能贴上来吗?
zhuqian0313@126.com

  回复  引用    
#11楼2007-11-30 12:03 | xiaozhunic[未注册用户]
呵呵,楼主人真好!
路过学习中,谢谢!!
  回复  引用    
#13楼2008-12-26 16:30 | 汪岩[未注册用户]
做的不错,实现了自定义功能



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 286521




相关文章:

相关链接: