Boost Spirit x3 не компилируется

Я слежу за документацией x3 на веб-сайте boost и попытался дополнить пример того, как организовать код, с помощью вещей, описанных в примере с аннотациями, который следует за ним. При компиляции проекта (с g ++ или MSVC) возникает следующая ошибка:

ошибка: нет соответствующей функции для вызова 'boost :: spirit :: x3 :: unused_type :: get ()'

В первой строке функции on_success в следующем коде:

// tag used to get the position cache from the context
struct annotate_position
{
    template <typename T, typename Iterator, typename Context>
    inline void on_success(const Iterator &first, const Iterator &last, T &ast, const Context &context)
    {
        auto &position_cache = x3::get<position_cache_tag>(context).get();
        position_cache.annotate(ast, first, last);
    }
};

Код можно найти здесь: Github.

Пример аннотаций - это почти тот же код, только в одном файле, поэтому я не могу понять, что не так ...


person Etchelon    schedule 30.07.2019    source источник


Ответы (1)


В аннотации используется директива with<>. Это изменяет контекст для этих правил.

Однако контекст был жестко закодирован в config.hpp, потому что это позволяет разделить определения правил в их собственной единице перевода (исходный файл).

Чтобы исправить это напрямую:

struct position_cache_tag;
using position_cache = boost::spirit::x3::position_cache<std::vector<iterator_type>>;

using simple_context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;

using context_type = boost::spirit::x3::context<
    client::parser::position_cache_tag,
    std::reference_wrapper<position_cache>, 
    simple_context_type
>;

Это уже должно работать. Однако вы обнаружите, что чего-то не хватает, потому что старая функция parse в main (без аннотаций позиций) также была там. В принципе добавление тройки вроде

BOOST_SPIRIT_INSTANTIATE(person_type, iterator_type, simple_context_type)
BOOST_SPIRIT_INSTANTIATE(employee_type, iterator_type, simple_context_type)
BOOST_SPIRIT_INSTANTIATE(employees_type, iterator_type, simple_context_type)

было бы достаточно для облегчения, но тогда, очевидно, код аннотации в on_success не будет компилироваться. Если хотите, можете сами SFINAE выбраться из этого беспорядка, но я только что удалил неиспользуемый код из main.cpp.

БОНУС

В качестве бонуса в наши дни вы можете обойтись без reference_wrapper, поскольку я вижу, что вы используете Boost 1.70.

Раньше ссылочная оболочка требовалась для изменяемого состояния в директивах, но недавно я узнал (Spirit X3, полезен ли этот подход к обработке ошибок?), который больше не требуется. Поэтому вы можете упростить контекст:

using context_type = boost::spirit::x3::context<
    client::parser::position_cache_tag,
    position_cache, 
    simple_context_type
>;

И отбросьте ссылочную оболочку с обоих концов:

auto &position_cache = x3::get<position_cache_tag>(context); // NOTE: no more .get()

А также

auto const parser =
    with<position_cache_tag>(positions)[client::employees()];

Полный код (Github)

Вот мой рабочий код: https://github.com/sehe/corrupted-spirit, содержащий следующие коммиты по порядку, поэтому легко найти, что изменилось, почему:

commit 2d1d553afab53d7a83620406c2dcd50967bf2765
Date:   Wed Jul 31 22:50:49 2019 +0200

    Build tweaks

    Make it compile on my linux box, and adding some minimum
    debug/sanitizer/diagnostics flags

commit 98a989bb165d0b25b6919449d4dd09f7656168c8
Date:   Wed Jul 31 22:51:50 2019 +0200

    Various compiler wanrings, no impact

commit 91f5c607c10a489e2d7b9e45dca55438d05419a2
Date:   Wed Jul 31 22:53:46 2019 +0200

    Fixed style issues in main.cpp

     - using namespace (my first hunch was with `ref` being std::ref instead
     of boost::ref, but that turned out a red herring. Better to be explicit
     though

     - added condition on use of ast[1]

commit 084700c80023d4fb291bee36f41cb99f23f7dffa
Date:   Wed Jul 31 22:51:20 2019 +0200

    Fix the context_type in config.hpp

commit df7f9505e042b93bcd62167090e89008788218de (HEAD -> master, sehe/master)
Date:   Wed Jul 31 22:56:20 2019 +0200

    Simplify the with directive

    1.70.0 no longer requires manual ref() for with directives with mutable
    context items.
person sehe    schedule 31.07.2019
comment
Кстати спасибо за ответ, забыл сделать раньше. Это немного помогло мне вспомнить, как думать о коде на C ++, которым я давно не пользовался ... - person Etchelon; 09.08.2019
comment
Я могу представить :) Я забываю детали всего, что не использую изо дня в день - person sehe; 09.08.2019