1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <boost/spirit.hpp>
int main()
{
using namespace boost::spirit;
using namespace std;
rule<phrase_scanner_t> factor, term, exp;
// 因子 = 实数 | '(' , 表达式 , ')';
factor = real_p | ('(' >> exp >> ')');
// factor = real_p | !(ch_p('+')|ch_p('-')) >> ('(' >> exp >> ')')
// 上面注释部分是括号前可以带正负号的规则

// 乘除计算 = 因子,{('*',因子)|('/',因子)};
term = factor >> *(('*' >> factor) | ('/' >> factor));
// 表达式 = 乘除计算,{('+',乘除计算)|('-',乘除计算)};
exp = term >> *(('+' >> term) | ('-' >> term));

const char* szExp = "(2+3)";
parse_info<> rule = parse(szExp, exp, space_p);
cout << "parse " << (rule.full ? "success" : "fail") << endl;
return 0;
}

解析四则运算表达式,要把EBNF规则写出来:
//实数或者是括号包围的子表达式
real_p | (‘(‘ >> exp >> ‘)’); // 因子 = 实数 | ‘(‘ , 表达式 , ‘)’;
//因子因子或因子/因子,可连续乘除也可只是一个因子
乘除计算 = 因子,{(‘
‘,因子)|(‘/‘,因子)};
//加减计算,与上面类似
表达式 = 乘除计算,{(‘+’,乘除计算)|(‘-‘,乘除计算)}; 这个定义已经隐含了优先级:
要计算表达式(加减计算),必然要先计算乘除计算;
要计算乘除计算,就要先计算因子;
要计算因子,要么得到一个数字,要么就要计算括号内的子表达式。