使用普通精神解析器进行分割错误

时间:2015-10-25 01:36:50

标签: c++ parsing c++11 boost-spirit boost-spirit-qi

在过去的几个月里,我经常使用spirit::qi。但是,这次我遇到了一个我真的无法理解的段错误。

我已将它缩减为极小的测试用例,语法定义为12行代码。

这感觉很像earlier question,但在那里解决方案是将.alias()添加到某些终端,以便qi不会复制它们,并且#&# 39;似乎解决了这个问题。

我担心我在这里缺少一些基本的东西,因为我设法制作了比这更复杂的语法,完全按照我的预期方式进行测试。 / p>

现在我唯一想到的是,或许qi只是不喜欢主要的语法返回类型是一个提升变体?我不知道我之前是否制作过任何语法。我想我接下来会对此进行测试,但说实话,我一直在旋转我的轮子,摆弄这样的东西一段时间。

我可以确认,如果设置mod_规则的行被注释掉,则不会发生段错误,程序正常运行完成。

编辑:实际上,即使删除了所有语法属性,也会出现段错误。

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <iostream>

typedef unsigned int uint;

namespace qi = boost::spirit::qi;

/***
 * Grammar
 */
template <typename Iterator>
struct op_grammar : qi::grammar<Iterator> {
  qi::rule<Iterator> constant_;
  qi::rule<Iterator> mod_;
  qi::rule<Iterator> expr_;

  op_grammar() : op_grammar::base_type(expr_) {
    constant_ = qi::uint_;
    expr_ = mod_ | constant_;
    mod_ = expr_ >> qi::lit('%') >> expr_; 
  }
};

/***
 * Test
 */
int main() {
//  std::string str{"n % 2"};
  std::string str{"2"};

  typedef std::string::const_iterator str_it;
  str_it it = str.begin();
  str_it end = str.end();
  op_grammar<str_it> grammar;

  if (qi::parse(it, end, grammar) && it == end) {
    std::cerr << "Good\n";
  } else {
    std::cerr << "Bad\n";
  }
}

1 个答案:

答案 0 :(得分:1)

实际上,我想出来了......

问题是,如同编写的那样,语法存在缺陷,并且无法解析它。因为expr_的第一个非终结点是mod_mod_的第一个非终结符是expr_,所以甚至无法开始弄清楚如何解析他们中的任何一个,都是循环的。

可以通过将expr_的{​​{1}}更改为mod_来修复语法,然后按预期工作。

我会在这里留下这个答案我猜是因为问题已经得到了投票,但可能我应该删除这个问题,不确定。