一个数字的提升精神解析器的分段错误
Segmentation fault with boost spirit parser for one digit
我正在尝试使用 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
您正在使用 auto,但没有深度复制 Proto 表达式树。这会创建悬挂引用,因此 Undefined Behaviour.
这是一个修复方法(也请注意更短的书写方式):
auto const nonZero = qi::copy(qi::char_("1-3"));
你也可以只写
auto const nonZero = qi::copy(qi::digit - '0');
所有其他示例 "working" 仍然是未定义行为 (UB)。如果你越界,任何事情都可能发生。
现场演示
#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'
我正在尝试使用 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
您正在使用 auto,但没有深度复制 Proto 表达式树。这会创建悬挂引用,因此 Undefined Behaviour.
这是一个修复方法(也请注意更短的书写方式):
auto const nonZero = qi::copy(qi::char_("1-3"));
你也可以只写
auto const nonZero = qi::copy(qi::digit - '0');
所有其他示例 "working" 仍然是未定义行为 (UB)。如果你越界,任何事情都可能发生。
现场演示
#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'