2

因此,我在 boost::spirit::x3 中遇到了 boost::spirit::x3 的奇怪行为,如 boost 1.59 中提供的:

我通过以下方式定义了一个“动态”符号表:

struct instructions : x3::symbols<OpCode> {
    instructions()
    {
        name("instructions");
    }

    void set_instruction_set(const std::unordered_map<std::string, OpCode>& instruction_set) {
        for (const auto& var : instruction_set) {
            add(var.first, var.second);
        }
    }
} instructions_parser;

OpCode定义为

struct OpCode
{
    std::string mnemonic;
    std::vector<...> variants;// actual type in vector<> not important.
};

现在,在解析输入字符串时,将符号表嵌入到必要的规则中,例如

mov r2  r1
mov r1  @80

结果 ast 仅包含第一个mov及其操作数。缺少第二个 mov 但操作数已正确解析。在打印生成的 AST 时,这可能如下所示:

mov r2 r1 
    r1 @80

使用调试器,我在 symbols.hpp 中找到了错误的来源symbol_parser::parse()

template <typename Iterator, typename Context, typename Attribute>
    bool parse(Iterator& first, Iterator const& last
      , Context const& context, unused_type, Attribute& attr) const
    {
        x3::skip_over(first, last, context);

        if (value_type* val_ptr
            = lookup->find(first, last, get_case_compare<Encoding>(context)))
        {
            x3::traits::move_to(*val_ptr, attr); //<- the error originates from here
            return true;
        }
        return false;
    }

move_to蜜蜂:

template <typename T>
inline void move_to(T& src, T& dest)
{
    if (boost::addressof(src) != boost::addressof(dest))
        dest = std::move(src);
}

如您所见,src我在 symbol_parser 中添加的 OpCode 实例已被移动。这意味着在第一次调用它之后再次为空,这就是为什么只出现第一条指令。简单地说,它已从符号表中移出。

现在最后我的问题是: 这是一个错误还是我犯了一个错误?

4

1 回答 1

3

正如sehe建议的那样,我的解决方法是:

我找到了一个临时解决方法:通过将模板参数声明为 const 可以抑制移动语义。然后调用copy-ctor。

IE:x3::symbols<const std::string>

于 2016-02-23T21:28:58.713 回答