x3 :: symbols перемещает результат и поэтому удаляет его из самого symbol_parser

Итак, я столкнулся со странным поведением с 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

результирующий аст содержит только первый 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 который является моим экземпляром OpCode, добавленным в symbol_parser, перемещен. Это означает, что после первого вызова он снова пуст, и поэтому появляются только первые инструкции. Проще говоря, он перемещен из таблицы символов.

Теперь наконец мой вопрос:
Это ошибка или я ошибаюсь?

2

Решение

Как предложил sehe мой обходной путь в качестве ответа:

Я нашел временное решение: объявив параметр шаблона как const, можно подавить семантику перемещения. Затем вызывается copy-ctor.

т.е .: x3::symbols<const std::string>

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector