简单的 Spirit Parser 语法的分段错误
我的 Spirit Qi 解析器经常遇到段错误。
在花了几天时间调试这个问题之后(我发现堆栈跟踪不可能被理解),我决定将其缩减为一个最小的示例。谁能告诉我我做错了什么(如果有的话)?
将代码保存为 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
Or,使用 boost 1.46.1 它将报告 Spirit version: 2042
I'm running into frequent segfaults with my Spirit Qi parser.
After spending days to debug the issue (I found the stacktraces impossible to grok) I decided to trim it down to a minimal example. Can anyone tell what I'm doing wrong, if anything?
Save code as bug.cpp, compile with g++ -Wall -o bug bug.cpp
and you should be good to go.
//#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;
}
I've tested this with
- g++ 4.4, 4.5, 4.6 and
- boost versions 1.42 (ubuntu meerkat) and 1.46.1.1 (natty)
The output is
sehe@meerkat:/tmp$ ./bug
Spirit version: 2020
Segmentation fault
Or, with boost 1.46.1 it will report Spirit version: 2042
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
按照您在答案中建议的方式更改初始化顺序只会隐藏问题。实际问题是,
rule
具有正确的 C++ 复制语义。您可以通过将语法初始化重写为来解决此问题:有关基本原理和更详细的解释,请参阅 这里。
Changing the initialization order as you suggested in your answer just hides the problem. The actual problem is, that
rule<>
's have proper C++ copy semantics. You can fix this by rewriting your gramar initialization as:For a rationale and a more detailed explanation, see here.