Reputation: 103
I have to use boost::spirit for parsing, and I want use phrase_parse function :
qi::phrase_parse(str.begin(), str.end(), grammar, ascii::space - qi::eol);
But the fourth term (ascii::space - qi::eol), isnt allowed by my compiler. How can I use the skipper ascii::space WITHOUT skipping eol ?
Upvotes: 10
Views: 4444
Reputation: 393134
The simplest answer is
qi::phrase_parse(str.begin(), str.end(), grammar, ascii::blank);
Of course, it depends on your grammar too: if it expects a specific skipper class you might need to change that. See below for a generic way to handle that (although you could just specify qi::blank_type
for a Grammar that should only accept qi::blank
).
The sample handles arbitrary skippers too.
Spirit has several directives that influence the use of skippers:
will parse the sub-expression regardless of skipper (useful for e.g. string literals in a grammar)
will return the raw source iterator range, meaning that skipped input will be included in the result
can be used to explicitely change the type of skipper used for the subexpression
The Boost Spirit site has a nice article about things like this
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
template <typename It, typename Skipper>
struct parser : qi::grammar<It, Skipper>
{
parser() : parser::base_type(start)
{
start = *qi::int_;
}
private:
qi::rule<It, Skipper> start;
};
template <typename C, typename Skipper>
void doParse(const C& input, const Skipper& skipper)
{
auto f(std::begin(input)), l(std::end(input));
parser<decltype(f), Skipper> p;
bool ok = qi::phrase_parse(f,l,p,skipper);
if (ok)
std::cout << "parse success\n";
}
int main()
{
const std::string input = "1 2 3 4";
doParse(input, qi::blank);
doParse(input, qi::space);
doParse(input, ~qi::char_("0-9"));
}
Upvotes: 16