发布一个基于Spirit的表达式解析库

整个库只有一个Expr2.h文件,它主要基于Boost中的Spirit库和Function库实现。适用于VC(7.1以上),C++Builder和GCC。

最简用法:

  1. CEquation equ;
  2. IOpPtr op = equ.CreateOperator("1+2*3/(4+5)^6");
  3. double result = op->Op(NULL);

CEquation支持加减乘除和幂操作

定位解析错误位置:

  1. const char* exp = "1+2*3/((4+5)"//错误的表达式
  2. const char* lastp;
  3. IOpPtr op = equ.CreateOperator(exp, &lastp); // lastp指出最后解析的位置
  4. if(!op)
  5. {
  6.     cout << std::string(exp,lastp) << "<这里有错误>" << lastp << endl;
  7. }

在表达式中使用常量

  1. CEquation equ;
  2. // 加入常量
  3. equ.AddConst("e",2.1718);
  4. equ.AddConst("pi",3.1415926);
  5.  
  6. IOpPtr op = equ.CreateOperator("1+e*3/(pi+5)");
  7. double result = op->Op(NULL);

为CEquation类加入函数支持

光有加减乘除是不够的,CEquation还支持实时加入函数支持。

  1. CEquation equ;
  2. // 加入函数
  3. equ.AddUnaryFunc("sin", (double (*)(double))sin);
  4. equ.AddUnaryFunc("dao", bind1st( divides<double>(), 1.0 ) ); //倒数
  5. IOpPtr op = equ.CreateOperator("1+dao(e*3)/sin(pi+5)");
  6. double result = op->Op(NULL);

AddUnaryFunc方法接收一个字符串和一个要求形式为double func(double)的函数或仿函数。字符串作为表达式中的函数名。另外,还有一个AddBinaryFunc方法,用于加入两个参数的函数(如atan2)。

支持表达式中的变量

当表达式中有字母并且不属于常量时,CEquation类将其它作为变量处理

  1. CEquation equ;
  2. IOpPtr op = equ.CreateOperator("1+sin(pi/X)^Y");
  3. cout << "变量名:";
  4. const CVariableList &vl = op->GetVariables();
  5. for(CVariableList::const_iterator itr=vl.begin(); itr!=vl.end(); ++itr)
  6. {
  7.     cout << itr->Name << " , ";
  8. }
  9. cout << endl << "X=10, Y=5 时,方程的解:";
  10. double v[]={10,5}; //按变量出现的顺序写变量对应的数值
  11. cout << op->Op(v) << endl;

    IOpPtr的GetVariables方法返回表达式中所有的变量(CVariableList 其实是一个vector<TVariable>),TVariable结构中只有一个Name成员。

使用字符串表达式加入常量

除了使用AddConst方法外,CEquation也能识别字符串表达式中的常量定义:

  1. CEquation equ;
  2. equ.AddEquation("G = 9.8");
  3. IOpPtr op = equ.CreateOperator("1+G*3");
  4. double result = op->Op(NULL);

AddEquation方法接受的字符串表达式必须为"名称=公式"的形式。

多级定义

AddEquation不仅可以自动识别常量,也可以把整个公式赋值给一个变量。当字符串中"="右边的公式含有变量时,就相当于定义一个子公式,如:

  1. CEquation equ;
  2. ...
  3. equ.AddEquation("f = 1+sin(pi/X)^Y");   //定义f
  4. IOpPtr op = equ.CreateOperator("f*(20/Y)");  //f作为1+sin(pi/X)^Y被代入
  5. ...

函数定义(C++Builder 2006以下版本不适用)

还是AddEquation方法,如果等号左边的形式是:函数名(变量,变量,...)的形式。那么将生成一个新的函数:

  1. CEquation equ;
  2. equ.AddConst("e",2.1718);
  3. equ.AddUnaryFunc("lg", p_unary_f(std::log10));
  4. equ.AddEquation("log(base, exp) = lg(exp)/lg(base)");
  5. equ.AddEquation("ln(x) = log(e,x)"); //新生成一个ln函数
  6. IOpPtr op = equ.CreateOperator("ln(3)"); //使用ln函数

注:p_unary_f在Expr2中被定义为double (*p_unary_f)(double)

这个库是大小写敏感的,不过很简易通过改写TVariable的两个比较操作实现大小写不敏感。

BUG在所难免,如果大家有改进或修复一定要回复哦(基于GPL发布)!希望这个库能对大家有用

下载地址:http://www.cpp-prog.com/2009/0818/147.html

使用boost::sprirt编写的表达式解析器,代码很容易扩展,功能很强大,适合做功能强大的客户化定义程序。 -----------表达式解析--------- 已定义的函数有:PI,SIN,COS,TAN,,ABS,EXP,LOGN,POW,SQRT,FORMAT,LENGTH,SUBSTR 强制类型转换请使用:(数据类型)数据 例如:(int) "100" 的值为int型100 已定义的变量有:var1=123,var2=this is a string 请输入您的表达式>>1+2 计算结果:3 XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- 1+2 --> <parsetree version="1.0"> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="integer_const"> <value>1</value> </parsenode> <parsenode rule="integer_const"> <value>2</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:integer 计算结果:3 请输入您的表达式>>"ab"+"cd" 计算结果:"abcd" XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- "ab"+"cd" --> <parsetree version="1.0"> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="string_const"> <value>"ab"</value> </parsenode> <parsenode rule="string_const"> <value>"cd"</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:string 计算结果:abcd 请输入您的表达式>>format("1+2=%d",1+2) 计算结果:format("1+2=%d",3) XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- format("1+2=%d",1+2) --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>format</value> <parsenode rule="exprlist"> <parsenode rule="string_const"> <value>"1+2=%d"</value> </parsenode> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="integer_const"> <value>1</value> </parsenode> <parsenode rule="integer_const"> <value>2</value> </parsenode> </parsenode> </parsenode> </parsenode> </parsetree> 计算结果数据类型:string 计算结果:1+2=3 请输入您的表达式>>PI() 计算结果:PI() XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- PI() --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>PI</value> </parsenode> </parsetree> 计算结果数据类型:double 计算结果:3.1415926535897931 请输入您的表达式>>cos(1.5) 计算结果:cos(1.5) XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- cos(1.5) --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>cos</value> <parsenode rule="double_const"> <value>1.5</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:double 计算结果:0.070737201667702906 请输入您的表达式>>q
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值