Custom Skip Parser with Boost::Spirit
Asked Answered
U

1

19

The standard ascii::space_type skipper does of course not skip my comments. The docs mention you can make your own skip parser but there is no example of actually how to do it.

I'd just need an example code or anything, I've been googling for 2 hours now.

Please don't point me to the examples, the few links that work are hopelessly outdated, dealing with Spirit 1.6.

Unintentional answered 15/12, 2011 at 14:3 Comment(1)
Have you looked at the examples that come with the Boost distribution?Dichromate
U
34

After some experimentation, I have found a way to specify a custom skipper and will outline it here:

template<typename Iterator>
struct pl0_skipper : public qi::grammar<Iterator> {

    pl0_skipper() : pl0_skipper::base_type(skip, "PL/0") {
        skip = ascii::space | ('{' >> *(qi::char_ - '}') >> '}');
    }
    qi::rule<Iterator> skip;
};

template<typename Iterator, typename Skipper = pl0_skipper<Iterator>>
struct pl0_grammar : public qi::grammar<Iterator, Skipper> {

    /* The rules use our skipper */
    qi::rule<Iterator, Skipper> start;
    qi::rule<Iterator, Skipper> block;
    qi::rule<Iterator, Skipper> statement;

};

The secret lies in the call of the parser. For some reason, when you want to parse this using parse_phrase, you have to give a skipper grammar object. I was not aware of this:

typedef std::string::const_iterator iterator_t;
typedef parser::pl0_grammar<iterator_t> grammar;
typedef parser::pl0_skipper<iterator_t> skipper;

grammar g;
skipper ws;

iterator_t iter = str.begin();
iterator_t end = str.end();
bool r = phrase_parse(iter, end, g, ws);

This works.

Unintentional answered 16/12, 2011 at 13:28 Comment(1)
Quite late comment here, but this saved me also a lot of work, so thank you for this answer.Trstram

© 2022 - 2024 — McMap. All rights reserved.