Search code examples
c++boost-spiritboost-spirit-qi

Spirit Qi: Error when replacing sequence with expectation operator


I have a grammar that works perfectly fine and contains the following lines.

element = container | list | pair;
container = name >> '(' >> -(arg % ',') >> ')' >> '{' >> +element > '}';
// trying to put an expectation operator here --------^
list = name >> '(' > (value % ',') > ')' > ';';
pair = name >> ':' > value > ';';

To have meaningful error messages, I want to make sure that container does not backtrack as soon as it hits '{'. But for some reason, if I replace the sequence operator with an expectation operator right after the '{', I get a huge compiler error. Any ideas what the problem might be?

element is a boost::variant; container, list and pair are own structs with BOOST_FUSION_ADAPT_STRUCT applied. Please have a look here for the full source code: https://github.com/fklemme/liberty_tool/blob/master/src/liberty_grammar.hpp#L24


Solution

  • Yes. Because the precedences of operator>> and operator> aren't equal, the resulting synthesized attribute type is different.

    In fact, it is no longer automatically compatible with the intended exposed attribute type.

    In this case the problem can be quickly neutralized with some disambiguating parentheses around the sub-expression:

    container = name >> '(' >> -(arg % ',') >> ')' >> ('{' > +element > '}');