我很难制作玩具语法来解析 Boost Spirit 中所需的附加工作。
这是我的语法和代码:
语法.h:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
void test();
template <typename Iterator>
struct ExpressionGrammar : qi::grammar<Iterator, double(), ascii::space_type>
{
qi::rule<Iterator, double(), ascii::space_type> expression;
qi::rule<Iterator, double(), ascii::space_type> addsub;
ExpressionGrammar()
: ExpressionGrammar::base_type(expression)
{
using qi::lit;
using qi::_val;
using qi::_1;
using qi::_2;
addsub = (expression >> '+' >> expression)[_val = _1 + _2];
expression = (qi::double_ | addsub);
}
};
语法.cpp:
#include "Syntax.h"
namespace qi = boost::spirit::qi;
void test()
{
ExpressionGrammar<const char*> grammar;
std::string s = "3 + 5";
const char* c = s.c_str();
double result = -42;
bool r = qi::phrase_parse(c, c+strlen(c), grammar, ascii::space, result);
if (r)
std::cout << "Success. result: "<<result<<". Still to parse: "<<c<<std::endl;
else
std::cout << "Fail. parsing failed at: "<< c <<std::endl;
}
输出:
Success. result: 3. Still to parse: + 5
似乎double_
消耗了3
,然后没有可以解析的规则+ 5
。但是,如果我将表达式规则更改为
expression = (addsub | qi::double_);
然后我的程序进入无限递归。
有什么办法解决这个问题?我知道在示例中更常见的是使用 Kleene 星来处理二进制组合的任意列表(沿线expression *('+' >> expression)
)。这是使用解析表达式语法的必要性吗?如果是,请解释原因。