segmentation fault with trivial spirit parser

我的未来我决定 提交于 2020-01-06 02:57:24

问题


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.

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

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.

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.

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.

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.

Edit: Actually, it segfaults even if all of the grammar attributions are deleted.

#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:


Actually, I figured it out...

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.

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.



来源:https://stackoverflow.com/questions/33325243/segmentation-fault-with-trivial-spirit-parser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!