Custom Skip Parser with Boost::Spirit

2019-01-17 07:49发布

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.

1条回答
Ridiculous、
2楼-- · 2019-01-17 07:58

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.

查看更多
登录 后发表回答