Boost.Spirit——60行代码实现一个计算器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Boost.Spirit——60行代码实现一个计算器
Boost.Spirit,利用递归下降法进行文法解析,可以解析LL(1)文法。
从编译原理的角度,LL(1)文法的描述能力比正则表达式要强,因此Boost.Spirit也是可以处理正则表达式的。
缺陷:Boost.Spirit采用模板来实现,虽然可以较高的运行效率,但无法在程序运行之时动态的产生一个解析器。因此一个用字符串表示的正则表达式,是无法用Boost.Spirit解析的。
利用Boost.Spirit实现的计算器代码如下。支持四则运算和括号。支持空格。
程序中还使用了Boost.Bind库和Boost.Function库。
#include
#include
#include
#include
#include
#include
#include
template
void CalStack(std::stack
assert(values.size() >= 2);
double op2 = values.top();
values.pop();
double op1 = values.top();
values.pop();
values.push(op()(op1, op2));
}
void eval(const char* expr) {
using boost::spirit::rule;
using boost::spirit::ch_p;
using boost::spirit::real_p;
using boost::spirit::space_p;
using boost::bind;
using boost::ref;
using std::stack;
typedef double Type;
stack
// E ::= T ( (+T) | (-T) )*
// T ::= F ( (*F) | (/F) )*
// F ::= ('(' E ')') | 浮点数
rule<> E, F, T;
E = (T >> *(
(ch_p('+') >> T)[bind(&CalStack
(ch_p('-') >> T)[bind(&CalStack
));
T = (F >> *(
(ch_p('*') >> F)[bind(&CalStack
(ch_p('/') >> F)[bind(&CalStack
));
F = (ch_p('(') >> E >> ch_p(')')) |
(*space_p >> real_p[bind(&stack
if (parse(expr, E).full) {
assert(sValueStack.size() == 1);
std::cout << sValueStack.top() << std::endl;
} else {
std::cout << "计算过程中遇到错误" << std::endl;
}
}
int main() {
std::string input;
while( std::getline(std::cin, input) ) {
eval(input.c_str());
}
}
代码在Visual Studio 2008 + Boost 1.36.0编译通过。