Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Skip Parser with Boost::Spirit

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.

like image 909
Lanbo Avatar asked Dec 15 '11 14:12

Lanbo


1 Answers

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.

like image 129
Lanbo Avatar answered Nov 04 '22 06:11

Lanbo