mavam
mavam

Reputation: 12552

Using Boost Spirit's stream parser with custom grammar

Synopsis

I would like to harness Boost Spirit's stream parser API to parse an std::istream incrementally. However, I could not find a good example of how to use it with an iterator-based grammar. Conceptually, my goal is to parse an infinite stream of objects of type T.

Details

A grammar in Qi with an attribute of type T and skipper S typically has the form:

template <typename Iterator>
struct grammar : qi::grammar<Iterator, T(), S>;

How do I use such a grammar with the stream-based API? Specifically, my mental model for the stream API is that I can do something along the lines of:

// Callback invoked for each successfully parsed instance of T.
void f(T const& x)
{
}


// What iterator type?
grammar<???> parser;
skipper<???> skipper;

T x;

std::ifstream ifs("/path/to/file");
ifs.unsetf(std::ios::skipws)
while (! ifs.eof())
{
    ifs >> phrase_match(parser, skipper, x);
    if (ifs.good() || ifs.eof())
        f(x);
}

I am struggling with bringing together traditional grammars requiring iterators. How does that fit together with the stream API?

Upvotes: 4

Views: 1199

Answers (1)

ildjarn
ildjarn

Reputation: 62975

You're missing the Spirit multi-pass iterator. Note, however, that parsing of the stream will not be done incrementally unless you go out of your way to make sure your grammar has minimal backtracking.

Upvotes: 3

Related Questions