分割错误与琐碎的精神解析器 [英] segmentation fault with trivial spirit parser

查看:245
本文介绍了分割错误与琐碎的精神解析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去几个月,我经常使用 spirit :: qi 。但是,这次我得到了一个segfault,我真的不能有任何意义。

I've been using spirit::qi quite often for the past several months. However, this time I got a segfault that I really can't make any sense out of.

我已经把它减少到极小的测试用例,语法定义12行代码。

I have reduced it to an extremely minimal test case, the grammar definition is 12 lines of code.

这感觉很像一个早期问题但是解决方案,添加 .alias()到一些终端,使 qi 不会复制它们,似乎不能解决这个问题。

This feels a lot like an earlier question but the solution there, of adding .alias() to some of the terminals so that qi doesn't make copies of them, doesn't seem to fix this.

我担心, m缺少这里,因为我已经设法使方式更复杂的语法比这个测试完全按照我期望的方式。

I'm concerned that there's something fundamental I'm missing here, since I've managed to make way more complicated grammars than this that test out exactly the way I expect.

现在发生的唯一事情是那么,也许qi只是不喜欢主要的语法返回类型是一个boost变量?我不知道我是否有过这样的语法。我想我会测试下一个,但老实说,我一直在纺我的轮子fiddling这样的东西一会儿。

The only thing that occurs to me now is that, maybe qi just doesn't like for the main grammar return type to be a boost variant? I don't know if I have made any grammars that do that before. I guess I'll test this next but honestly I've been spinning my wheels fiddling with things like that for a while.

我可以确认,如果行设置 mod _ 规则被注释掉,则不会发生segfault,程序正常运行完成。

I can confirm that, if the line that sets up the mod_ rule is commented out, then no segfault occurs and the program runs normally to completion.

#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";
  }
}


推荐答案

,我想出来了...

Actually, I figured it out...

问题是,如所写的,语法是有缺陷的,没有办法可以解析。因为, expr _ 的第一个非终结符是 mod _ ,而第一个非终结符 mod_ expr _ ,所以没有办法甚至开始弄明白如何解析它们,它是循环的。

The problem is that as written, the grammar is flawed and there's no way that it can be parsed. Because, the first non-terminal of expr_ is mod_, and the first nonterminal of mod_ is expr_, so there's no way even to begin to figure out how to parse either of them, it's circular.

语法可以通过将 mod _ 的第一个 expr _ 更改为 constant _ ,然后按预期工作。

The grammar can be fixed by changing the first expr_ of mod_ to constant_ and then it works as expected.

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

I will leave this answer here I guess because the question already got an up-vote, but possibly I should just delete the question, not sure.

这篇关于分割错误与琐碎的精神解析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆