我正在尝试使用Boost.Spirit。 当我测试一个非常简单的解析器时,它只能解析一个数字,程序会崩溃。
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
auto const noneZero = qi::char_('1') |
qi::char_('2') |
qi::char_('3');
int main(int argc, char** argv)
{
std::string input = "9";
std::string output;
if (qi::parse(input.begin(), input.end(), noneZero, output))
{
std::cout << "Ok => '" << output << "'\n";
}
else
{
std::cout << "No\n";
}
return 0;
}
我做错了什么? 这应该是一个非常简单的案例,我无法弄清楚我做错了什么。
陌生人,如果我写下面的代码一切正常...... 但为什么?!语法应该是相同的,不是吗?
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
auto const noneZero = qi::char_('1', '9');
int main(int argc, char** argv)
{
std::string input = "9";
std::string output;
if (qi::parse(input.begin(), input.end(), noneZero, output))
{
std::cout << "Ok => '" << output << "'\n";
}
else
{
std::cout << "No\n";
}
return 0;
}
更有趣的是,以下程序不会崩溃:
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
auto const noneZero = qi::char_('1') |
qi::char_('2');
int main(int argc, char** argv)
{
std::string input = "9";
std::string output;
if (qi::parse(input.begin(), input.end(), noneZero, output))
{
std::cout << "Ok => '" << output << "'\n";
}
else
{
std::cout << "No\n";
}
return 0;
}
有人可以解释为什么这个语法不会崩溃:
auto const noneZero = qi::char_('1') |
qi::char_('2');
为什么这个语法崩溃:
auto const noneZero = qi::char_('1') |
qi::char_('2') |
qi::char_('3');
在我自己的计算机上怀疑有问题,我在coliru上尝试了所有这些例子,结果相同。 所有这些示例都使用以下命令编译:
clang++ test.cpp -Wall -Werror -Wextra --std=c++14
答案 0 :(得分:3)
您正在使用auto,而不会深入复制Proto表达式树。这会创建悬空引用,因此Undefined Behaviour。
这是一个修复程序(请注意编写它的更短方法):
auto const nonZero = qi::copy(qi::char_("1-3"));
你也可以写
auto const nonZero = qi::copy(qi::digit - '0');
所有其他样品&#34;工作&#34;仍然是未定义的行为(UB)。如果你不在线,任何事都会发生。
<强> Live On Coliru 强>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
auto const nonZero = qi::copy(qi::char_("1-9"));
int main(int argc, char** argv)
{
std::string input = "9";
std::string output;
if (qi::parse(input.begin(), input.end(), nonZero, output))
{
std::cout << "Ok => '" << output << "'\n";
}
else
{
std::cout << "No\n";
}
return 0;
}
打印
Ok => '9'