Boost Spirit x3 not compiling

北慕城南 提交于 2020-01-01 19:30:49

问题


I'm following the x3 documentation on the boost website, and I've tried to augment the example on how to organize code with the stuff explained in the annotations example that comes after. I'm having the following error when compiling the project (either with g++ or MSVC):

error: no matching function for call to 'boost::spirit::x3::unused_type::get()'

In the first line of function on_success in the following code:

// 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);
    }
};

Code can be found here: Github.

The annotations example is almost the exact same code, just in a single file, so I can't figure out what's wrong...


回答1:


The annotation uses the with<> directive. That modifies the context for those rules.

The context, however, had been hard-coded in config.hpp because that enables the rule definitions to be separated in their own translation unit (source file).

To fix it directly:

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
>;

That should already work. However, you'll find other things missing because the old parse function in main (without position annotations) was also still there. In principle adding a triplet like

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)

would be enough to alleviate, but then, obviously, the annotation code in on_success will not compile. If you want, you can SFINAE yourself out of that mess, but I just removed the unused code from main.cpp.

BONUS

As a bonus, you can do without the reference_wrapper these days, since I see you're using Boost 1.70.

The reference-wrapper used to be required for mutable state in with directives, but I found out recently (Spirit X3, Is this error handling approach useful?) that that's no longer required. Therefore you can simplify the context:

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

And drop the reference wrapper on both ends:

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

And

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

Full Code (Github)

Here's my working code: https://github.com/sehe/corrupted-spirit containing the following commits in order, so it's easy to find what changed why:

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.


来源:https://stackoverflow.com/questions/57262850/boost-spirit-x3-not-compiling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!