Boost Spirit lexeme vs no_skip

Viewed 265

As like the description on Boost.Spirit, the only difference between lexeme and no_skip is the pre_skip.

But after some test, I'm still confusing about the exactly meaning for pre_skip.

So what kind of condition will make a difference, maybe a example can help me understand it much better.

Thanks!

2 Answers

Pre-skip ignores whitespace at the start of the expression.

Contrasting:

Live On Coliru

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
static std::string const input = " 42j";

int main() {
    auto run_test = [](auto p) {
        auto f = input.begin(), l = input.end();
        int i;
        return qi::phrase_parse(f, l, p, qi::space, i)
            ? std::to_string(i)
            : "unparsed";
    };

    std::cout << "no_skip: " << run_test(qi::no_skip[ qi::int_ >> 'j' ]) << "\n";
    std::cout << "lexeme: "  << run_test(qi::lexeme[ qi::int_ >> 'j' ]) << "\n";
}

Prints:

no_skip: unparsed
lexeme: 42

As you can see lexeme will silently eat the leading white space. That's the pre-skip.

Tecnically speaking skipping happens before calling rules parser. So all directives within a lexeme parsing statement will act as an atom, skipper will be invoked before the begining of the lexeme clause as usual but not between rules within the clause.

The no_skip directive "wont invoke" any skipper at all as stated by the documentation. It will act as lexeme if there is no white space to skip, but that's a subtle difference. It's more appropriate when parsing binary files.

Related