Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spirit X3, semantic action makes compilation fails with: Attribute does not have the expected size

This code does not compiles (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());
}

It fails with a static assertion:

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

Thanks to wandbox I also tryied boost 1.61 and clang, both produce the same results.

If I remove the semantic action attached to portal, it compiles fine; the same happens if I change dest to:

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

Any help would be appreciated. TIA.

like image 305
dvd Avatar asked Jul 05 '16 22:07

dvd


1 Answers

This is surprising to me too, I'd report it at the mailing list (or the bug tracker) as a potential bug.

Meanwhile, you can "fix" it by supplying an attribute type for 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());
}

Prints:

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

NOTE I changed char_('P') into just lit('P') because I didn't want to complicate the sample dealing with the character in the attribute. Perhaps you didn't mean to have it in the exposed attribute anyways.

like image 183
sehe Avatar answered Oct 03 '22 05:10

sehe