I have this Spirit X3 parser
auto xyz_def =
x3::omit[x3::int_] >> x3::eol >>
(x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
(*(chemical::parser::atom >> x3::eol)
;
Which parses, with no problem something like this
2
Comment
H 1.2 3.2 4.5
C 1.1 9.1 8.5
Now I want to use (instead of completely ignoring) the first integer as a hint to help build the vector (from the Kleen*). To do that I do:
auto xyz_def =
x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >>
(x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
(*(chemical::parser::atom >> x3::eol)
;
However, when I do this, although the parsing function succeed, I have an empty result. This is particularly mysterious because the sematic action, in principle, has no salient side effect.
I found this workaround, which was to introduce all the sematic actions explicitly.
auto xyz_def =
x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >>
(x3::lexeme[+(x3::char_ - x3::eol)])[([](auto& ctx){x3::_val(ctx).comment = x3::_attr(ctx);})] >> x3::eol >>
(*(chemical::parser::atom >> x3::eol)[([](auto& ctx){x3::_val(ctx).atoms.insert(end(x3::_val(ctx).atoms), x3::_attr(ctx));})])
;
This is obviously an overkill. Why is it that when I add just one semantic actions in the first element, I have to add sematic actions for all?
I recently asked a similar question, but I was using the wrong version of Spirit (Qi) and I am also using attributes now instead of capturing lambdas, so that I can define self-contained rules.
The full code is here, can be pasted in https://wandbox.org/