Sen Sen - 2 months ago 10x
C++ Question

Starting with Spirit X3

I've just started using Spirit X3 and I have a little question related with my first test. Do you know why this function is returning "false"?

bool parse()
std::string rc = "a 6 literal 8";

auto iter_begin = rc.begin();
auto iter_end = rc.end();

bool bOK= phrase_parse( iter_begin, iter_end,
// ----- start parser -----

alpha >> *alnum >> "literal" >> *alnum

// ----- end parser -----
, space);

return bOK && iter_begin == iter_end;

I've seen the problem is related with how I write the grammar. If I replace it with this one, it returns "true"

alpha >> -alnum >> "literal" >> *alnum

I'm using the Spirit version included in Boost 1.61.0.

Thanks in advance,


jv_ jv_

Your problem is a combination of the greediness of operator * and the use of a skipper. You need to keep in mind that alnum is a PrimitiveParser and that means that before every time this parser is tried, Spirit will pre-skip, and so the behaviour of your parser is:

  • alpha parses a.
  • The kleene operator starts.
  • alnum skips the space and then parses 6.
  • alnum skips the space and then parses l.
  • alnum parses i.
  • ...
  • alnum parses l.
  • alnum skips the space and then parses 8.
  • alnum tries and fails to parse more. This completes the kleene operator with a parsed attribute of 6literal8.
  • "literal" tries and fails to parse.
  • The sequence operator fails and the invocation of phrase_parse returns false.

You can easily avoid this problem using the lexeme directive (barebones x3 docs, qi docs). Something like this should work:

alpha >> lexeme[*alnum] >> "literal" >> lexeme[*alnum];