因此,我在 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 实例已被移动。这意味着在第一次调用它之后再次为空,这就是为什么只出现第一条指令。简单地说,它已从符号表中移出。
现在最后我的问题是: 这是一个错误还是我犯了一个错误?