如何在Boost Spirit中尽早停止我的简单加法语法?

时间:2014-05-28 11:16:17

标签: c++ boost-spirit boost-spirit-qi peg

我很难制作玩具语法来解析Boost Spirit中所需的额外工作。

这是我的语法和代码:

Syntax.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);
    }
};

Syntax.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)的行)更常见。这是使用解析表达式语法的必要性吗?如果是这样,请解释原因。

1 个答案:

答案 0 :(得分:1)

Boost Spirit是一种递归下降解析器,它无法解析包含左递归的语法。看看this Wikipedia article如何重写左递归制作。精神上可能的解决方案包括使用Kleene Star表达式或列表运算符(%)。