【问题标题】:Parsing into a set using boost spirit x3使用 boost Spirit x3 解析成集合
【发布时间】:2016-06-21 23:09:18
【问题描述】:

我很感兴趣是否有一种方法可以使用 boost spirit x3 解析成一个集合。背景是我有一串标记,每个标记代表一个枚举值,现在我想创建一个解析器,它解析每个标记是否在字符串中最多一次,如果我能得到所有的解析,那将是一个魅力解析时将标记转换为std::set。 为了从解析的字符串中取回枚举,我使用了 symbol_table:

enum class foo{bar, baz, bla, huh};

    struct enum_table : x3::symbols<foo> {
        enum_table() {
            add("bar", foo::bar)
                    ("baz", foo::baz)
                    ("huh", foo::huh);
        }
    } const enum_parser;

【问题讨论】:

    标签: c++ parsing c++14 boost-spirit boost-spirit-x3


    【解决方案1】:

    我很感兴趣是否有一种方法可以使用 boost spirit x3 解析成一个集合。

    Spirit 可以开箱即用地解析为std::set&lt;&gt;(至少从 Boost 1.61.0 开始),因此以下内容已经适用于您显示的类型:

    std::set<foo> foos;
    x3::phrase_parse(
        input.begin(), input.end(),
        +enum_parser,
        x3::space,
        foos
    );
    

    Online Demo

    要让您的解析器在遇到重复项时失败,使用semantic actions 最容易做到这一点:

    std::set<foo> foos;
    auto insert_foo_or_fail = [&foos](auto& ctx) {
        _pass(ctx) = foos.insert(_attr(ctx)).second;
    };
    x3::phrase_parse(
        input.begin(), input.end(),
        +x3::omit[enum_parser[insert_foo_or_fail]],
        x3::space
    );
    

    Online Demo

    【讨论】:

    • 哦,哇,不知道它可以解析成一个开箱即用的集合。感谢语义动作的技巧
    • 这不适用于 boost 版本 1.60.0 我收到一个错误:»class std::set&lt;foo&gt;« has no member named »push_back« 所以这确实适用于 boost 版本 1.61.0
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2022-11-16
    相关资源
    最近更新 更多