1

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,

Sen

Wolf
  • 9,679
  • 7
  • 62
  • 108
Sen
  • 29
  • 5
  • Here you can test the code online: http://coliru.stacked-crooked.com/a/0ce333c6e9f75f66 – Sen Aug 02 '16 at 08:53

1 Answers1

1

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];
llonesmiz
  • 155
  • 2
  • 11
  • 20