琐碎的精神解析器语法的分段错误

Segmentation fault with trivial Spirit Parser grammar

本文关键字:语法 分段 错误      更新时间:2023-10-16

我的灵气解析器经常遇到段错误。

在花了几天时间调试问题(我发现堆栈跟踪无法摸索)后,我决定将其缩减为一个最小的示例。谁能说出我做错了什么,如果有的话?

将代码保存为 bug.cpp,使用 g++ -Wall -o bug bug.cpp 编译,您应该很高兴。

//#define BOOST_SPIRIT_DEBUG_PRINT_SOME 80
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/version.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
namespace /*anon*/
{
    using namespace boost::spirit::qi;
    template <typename Iterator, typename
        Skipper> struct bug_demo : 
            public grammar<Iterator, Skipper>
    {
        bug_demo() : 
            grammar<Iterator, Skipper>(story, "bug"),
            story(the),
            the("the")
        {
//          BOOST_SPIRIT_DEBUG_NODE(story);
//          BOOST_SPIRIT_DEBUG_NODE(the);
        }
        rule<Iterator, Skipper> story, the;
    };
    template <typename It>
        bool do_parse(It begin, It end)
    {
        bug_demo<It, space_type> grammar;
        return phrase_parse(begin, end, grammar, space);
    }
}
int main()
{
    std::cout << "Spirit version: " << std::hex << SPIRIT_VERSION << std::endl;
    try
    {
        std::string contents = "the lazy cow";
        if (do_parse(contents.begin(), contents.end()))
            return 0;
    } catch (std::exception e)
    {
        std::cerr << "exception: " << e.what() << std::endl;
    }
    return 255;
}

我已经测试过了

    g++ 4.4
  • 、4.5、4.6 和
  • Boost 版本 1.42 (Ubuntu Meerkat) 和 1.46.1.1 (natty)

输出为

sehe@meerkat:/tmp$ ./bug 
Spirit version: 2020
Segmentation fault

或者,在 boost 1.46.1 中,它将报告Spirit version: 2042

按照答案中的建议更改初始化顺序只会隐藏问题。实际的问题是,rule<>有适当的C++复制语义。您可以通过将语法初始化重写为:

bug_demo() : 
    grammar<Iterator, Skipper>(story, "bug"),
    story(the.alias()),
    the("the")
{}

有关基本原理和更详细的解释,请参阅此处。