Question

Consider the following parser:

#include <assert.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

struct command_toten_parser : qi::grammar<const char *, std::string()> {
    command_toten_parser() : command_toten_parser::base_type(r) {
        r = *qi::blank >> *qi::graph >> *qi::blank;
    }
    qi::rule<const char *, std::string()> r;
};

int main(int argc, char *argv[]) {
    command_toten_parser p;
    std::string c, s(" asdf a1 a2 ");
    const char *b = &*s.begin();
    const char *e = &*s.end();

    assert(qi::parse(b, e, p, c));
    std::string rest(b, e);

    assert(c == std::string("asdf"));
    assert(rest == std::string("a1 a2 "));

    return 0;
}

How to I change my parser such that part matched by *qi::blank is not captured (and my assertions passes)

Was it helpful?

Solution

You'd typically use a skipper:

qi::phrase_parse(b, e, +qi::graph, qi::blank, c);

Would parse into c == "asdfa1a2". Clearly, you want to disallow skipping "inside" the token, let's call in qi::lexeme:

qi::phrase_parse(b, e, qi::lexeme [+qi::graph], qi::blank, c);

Which parses "asdf" and leaves "a1 a2 " unparsed.

Fully adjusted sample showing how you'd use a configurable skipper with your grammar struct:

#include <assert.h>
#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

template <typename Skipper = qi::blank_type>
struct command_toten_parser : qi::grammar<const char *, std::string(), Skipper> {
    command_toten_parser() : command_toten_parser::base_type(r) {
        r = qi::lexeme [ +qi::graph ];
    }
    qi::rule<const char *, std::string(), Skipper> r;
};

int main(int argc, char *argv[]) {
    command_toten_parser<> p;
    std::string c, s(" asdf a1 a2 ");
    const char *b = &s[0];
    const char *e = b + s.size();

    assert(qi::phrase_parse(b, e, p, qi::blank, c));
    std::string rest(b, e);

    assert(c == std::string("asdf"));
    assert(rest == std::string("a1 a2 "));

    return 0;
}

See it Live On Coliru

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top