8

此代码无法编译(gcc 5.3.1 + boost 1.60):

#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

template <typename T>
void parse(T begin, T end) {
    auto dest = x3::lit('[') >> x3::int_ >> ';' >> x3::int_ >> ']';

    auto on_portal = [&](auto& ctx) {};
    auto portal    = (x3::char_('P') >> -dest)[on_portal];

    auto tiles = +portal;
    x3::phrase_parse(begin, end, tiles, x3::eol);
}

int main() {
    std::string x;
    parse(x.begin(), x.end());
}

它以静态断言失败:

error: static assertion failed: Attribute does not have the expected size.

感谢 wandbox,我还尝试了 boost 1.61 和 clang,两者都产生了相同的结果。

如果我删除附加到的语义动作portal,它编译得很好;如果我更改dest为:

auto dest = x3::lit('[') >> x3::int_ >> ']';

任何帮助,将不胜感激。TIA。

4

1 回答 1

4

这也让我感到惊讶,我会在邮件列表(或错误跟踪器)中将其报告为潜在错误。

同时,您可以通过提供以下属性类型来“修复”它dest

Live On Coliru

#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>

namespace x3 = boost::spirit::x3;

template <typename T>
void parse(T begin, T end) {
    auto dest = x3::rule<struct dest_type, std::tuple<int, int> > {} = '[' >> x3::int_ >> ';' >> x3::int_ >> ']';

    auto on_portal = [&](auto& ctx) {
        int a, b;
        if (auto tup = x3::_attr(ctx)) {
            std::tie(a, b) = *tup;
            std::cout << "Parsed [" << a << ", " << b << "]\n";
        }
    };
    auto portal    = ('P' >> -dest)[on_portal];

    auto tiles = +portal;
    x3::phrase_parse(begin, end, tiles, x3::eol);
}

int main() {
    std::string x = "P[1;2]P[3;4]P[5;6]";
    parse(x.begin(), x.end());
}

印刷:

Parsed [1, 2]
Parsed [3, 4]
Parsed [5, 6]

注意我更改char_('P')为只是lit('P')因为我不想使处理属性中字符的示例复杂化。也许您并不打算将它放在暴露的属性中。

于 2016-07-05T23:14:01.460 回答