您的位置:首页 > 其它

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

2009-08-18 21:00 162 查看
整个库只有一个Expr2.h文件,它主要基于Boost中的Spirit库和Function库实现。适用于VC(7.1以上),C++Builder和GCC。

最简用法:

CEquation equ;
IOpPtr op = equ.CreateOperator("1+2*3/(4+5)^6");

double result = op->Op(NULL);

CEquation支持加减乘除和幂操作

定位解析错误位置:

const char* exp = "1+2*3/((4+5)"; //错误的表达式

const char* lastp;

IOpPtr op = equ.CreateOperator(exp, &lastp); // lastp指出最后解析的位置

if(!op)
{
cout << std::string(exp,lastp) << "<这里有错误>" << lastp << endl;

}

在表达式中使用常量

CEquation equ;
// 加入常量
equ.AddConst("e",2.1718);

equ.AddConst("pi",3.1415926);

IOpPtr op = equ.CreateOperator("1+e*3/(pi+5)");

double result = op->Op(NULL);

为CEquation类加入函数支持

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

CEquation equ;
// 加入函数
equ.AddUnaryFunc("sin", (double (*)(double))sin);

equ.AddUnaryFunc("dao", bind1st( divides<double>(), 1.0 ) ); //倒数

IOpPtr op = equ.CreateOperator("1+dao(e*3)/sin(pi+5)");

double result = op->Op(NULL);

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

支持表达式中的变量

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

CEquation equ;
IOpPtr op = equ.CreateOperator("1+sin(pi/X)^Y");

cout << "变量名:";

const CVariableList &vl = op->GetVariables();

for(CVariableList::const_iterator itr=vl.begin(); itr!=vl.end(); ++itr)

{
cout << itr->Name << " , ";

}
cout << endl << "X=10, Y=5 时,方程的解:";

double v[]={10,5}; //按变量出现的顺序写变量对应的数值

cout << op->Op(v) << endl;

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

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

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

CEquation equ;
equ.AddEquation("G = 9.8");

IOpPtr op = equ.CreateOperator("1+G*3");

double result = op->Op(NULL);

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

多级定义

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

CEquation equ;
...
equ.AddEquation("f = 1+sin(pi/X)^Y"); //定义f

IOpPtr op = equ.CreateOperator("f*(20/Y)"); //f作为1+sin(pi/X)^Y被代入

...

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

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

CEquation equ;
equ.AddConst("e",2.1718);

equ.AddUnaryFunc("lg", p_unary_f(std::log10));

equ.AddEquation("log(base, exp) = lg(exp)/lg(base)");

equ.AddEquation("ln(x) = log(e,x)"); //新生成一个ln函数

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: