使用boost精神解析器进行一位数的分段错误

时间:2017-06-20 19:12:11

标签: c++ boost-spirit-qi

我正在尝试使用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

1 个答案:

答案 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'