Boost Spirit x3 未编译

Boost Spirit x3 not compiling

我正在关注 boost 网站上的 x3 文档,并尝试使用随后的注释示例中解释的内容来扩充有关如何组织代码的示例。 编译项目时出现以下错误(使用 g++ 或 MSVC):

error: no matching function for call to '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

注释示例几乎是完全相同的代码,只是在一个文件中,所以我不知道哪里出了问题...

注解使用了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
>;

那应该已经可以了。但是,您会发现缺少其他内容,因为 main 中的旧 parse 函数(没有位置注释)也仍然存在。原则上添加一个三元组,如

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。

with 指令中的可变状态过去需要引用包装器,但我最近 () 发现不再需要它了。因此,您可以简化上下文:

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.