发布一个基于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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值