Search code examples
boost-spirit-qi

How do boost::spirit::qi::parse() and boost::spirit::qi::phrase_parse() differ?


I'm new to Qi.

My goal is to use spirit::qi to create a CLI parser. By 'CLI parser' I do not mean the kind that processes command line options (e.g., app --help ) but something that processes commands typed by a user.

Example:

CLI> vacuum on
vacuum solenoid energized
CLI> 

I have been examining a number of spirit::qi examples and trying to understand qi. I see that qi provides two similar APIs: qi::parse() and qi::phrase_parse(). The example code I've examined uses both APIs, but I do not yet understand how they differ.

Put differently, I would think that each of these APIs are specialized for solving specific parsing tasks, but I do not understand, when trying to select one of these APIs to solve a particular parsing problem, which one should I choose.

My thanks in advance.


Solution

  • The "straight" parse API does not accept a skipper, whereas phrase_parse does.

    The skipper is a second parser expression that describes input sequences to be ignored outside of lexemes (like whitespace or comments, but not limited to that).

    To learn about the behaviour of skippers, see e.g. Boost spirit skipper issues

    In particular it will show that you can use parse() perfectly fine with grammars that employ skippers internally, because

    ok = phrase_parse(f, l, grammar, skipper, attr);
    

    is roughly equivalent to a "smarter" grammar that defines it internally:

    ok = parse(f, l, qi::skip(skipper)[grammar], attr);
    

    In fact I'd say that in 99% of cases this is the correct approach as the skipper is usually a property of the parser that cannot/should not be changed. Sadly for historical reasons the documentation examples are often using phrase_parse


    BONUS

    For some examples of command grammar parsing: