c++ - 嵌套 boost::variant 的段错误

标签 c++ boost boost-spirit boost-spirit-x3

以下程序已从原始程序中减少。我在运行时遇到段错误。如果我使用 ArithmeticUnaryExpression 删除第 24 行,则程序不再崩溃。如何消除段错误?

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/spirit/include/qi_expect.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>

#include <iostream>
#include <string>

namespace wctl_parser {

namespace x3 = boost::spirit::x3;
namespace ascii = x3::ascii;
namespace qi = boost::spirit::qi;

using x3::ulong_;
using x3::lexeme;

//--- Ast structures
struct ArithmeticUnaryExpression;
using AtomicProp = std::string;

using ArithmeticExpression = x3::variant<
    x3::forward_ast<ArithmeticUnaryExpression>,
    unsigned long
>;

struct ArithmeticUnaryExpression {
    std::string op;
    ArithmeticExpression operand;
};

using Expression = x3::variant<
    ArithmeticExpression
>;

template <typename T> auto rule = [](const char* name = typeid(T).name()) {
    struct _{};
    return x3::rule<_, T> {name};
};

template <typename T> auto as = [](auto p) { return rule<T>() = p; };

//--- Rules

x3::rule<struct aTrivRule, ArithmeticExpression> aTriv("aTriv");
x3::rule<struct exprRule, Expression> expr("expression");

auto const aTriv_def = rule<ArithmeticExpression>("aTriv")
    = ulong_
//  | '(' > expr > ')'
    ;

auto const primitive = rule<Expression>("primitive")
    = aTriv
    ;

auto const expr_def
    = primitive
    ;

BOOST_SPIRIT_DEFINE(aTriv)
BOOST_SPIRIT_DEFINE(expr)

auto const entry = x3::skip(ascii::space) [expr];

} //End namespace

int main() {

    std::string str("prop");
    namespace x3 = boost::spirit::x3;   
    wctl_parser::Expression root;
    auto iter = str.begin();
    auto end = str.end();
    bool r = false;
    r = parse(iter, end, wctl_parser::entry, root);
    if (r) {
        std::cout << "Parses OK:" << std::endl << str << std::endl;
        if (iter != end) std::cout << "Partial match" << std::endl;
        std::cout << std::endl << "----------------------------\n";
    }
    else {
        std::cout << "!! Parsing failed:" << std::endl << str << std::endl << std::endl << "----------------------------\n";
    }
    return 0;
}

最佳答案

你的变体

using ArithmeticExpression = x3::variant<
    x3::forward_ast<ArithmeticUnaryExpression>,
    unsigned long
>;

将默认构造为第一个元素类型。第一个元素类型包含 ArithmeticExpression,它也是默认构造的。你能看出问题所在了吗?

只要确保默认构造状态不会导致无限递归:

using ArithmeticExpression = x3::variant<
    unsigned long,
    x3::forward_ast<ArithmeticUnaryExpression>
>;

关于c++ - 嵌套 boost::variant 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47077381/

相关文章:

c++ - 有没有更有效的方法来替换这些多个 IF 语句?

c++ - 正则表达式:如何找到模式的最大整数值?

c++ - boost spirit x3 : parse into structs

c++ - boost::phoenix 中的逗号行为似乎不正确

c++函数式编程(boost::phoenix && boost::spirit)测试指针占位符中的空指针

php - 在文件中间覆盖

c++ - 运行时黑屏,没有错误

c++ - QT C++ QPainter - 如何正确使用 'this'

c++ - boost::asio 从套接字读取 n 个字节到 streambuf

c++ - std::find 和 boost::make_indirect_iterator - 编译错误