Boost logo

Boost Users :

From: Pedro Lamarão (pedro.lamarao_at_[hidden])
Date: 2006-01-25 12:30:04

Here follows a simple pattern to use Boost.Spirit to create a
"parseable" object, with a bonus formatted input operator, allowing you
quick access to formatter input for your type.

(Yeah, this stuff needs tweaking for better error handling, etc.)

class foo_thing {

    /* Other methods and stuff. */

    template <typename ForwardIterator>
    parse (ForwardIterator begin, ForwardIterator end);


    class grammar;

    /* Data members, etc. */

template <typename CharT, typename TraitsT>
std::basic_istream<CharT, TraitsT>&
operator>> (std::basic_istream<CharT, TraitsT>& i, foo_thing& thing) {
    using namespace std;
    using namespace boost::spirit;

    typedef multi_pass<istreambuf_iterator<CharT> > iterator_t;
    iterator_t begin(i);
    iterator_t end = make_multi_pass(istreambuf_iterator<CharT>());

    /* What if thing.parse() throws? */
    parse_info<iterator_t> info = thing.parse(begin, end);
    if (!info.hit)

    return i;

class foo_thing::grammar : public
boost::spirit::grammar<foo_thing::grammar> {

    grammar (foo_thing& thing) : _M_thing(thing) {}

    template <typename ScannerT>
    class definition;

    foo_thing mutable& _M_thing;

template <typename ScannerT>
class foo_thing::grammar::definition {

    /* Define this one; your parser ultimately writes to self._M_thing. */
    definition (foo_thing::grammar const& self);

    boost::spirit::rule<ScannerT> const& start () const;

    /* Populate with rules. */

template <typename IteratorT>
foo_thing::parse (IteratorT begin, IteratorT end) {
    namespace s = boost::spirit;
    grammar g(*this);
    s::parse_info<IteratorT> r = s::parse(begin, end, g);
    return r;

Pedro Lamarão
Intersix Technologies S.A.
SP: (55 11 3803-9300)
RJ: (55 21 3852-3240)
Your Security is our Business

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at