Boost logo

Boost Users :

Subject: [Boost-users] [Boost.Spirit] Skippers for sub-grammars
From: Vitaly Budovski (vbudovski+news_at_[hidden])
Date: 2010-10-22 04:50:53


Hello,

I've decided to break up my parser into sub-grammars to improve both
the readability and compile time. I'm now trying to specify a skip
parser for one of the sub-grammars, but I don't know how to do it. I'm
familiar with specifying a skip parser in the parse functions, but not
in the grammar itself. Could somebody please provide an example?
Thanks.

#include <boost/spirit/include/qi.hpp>
#include <string>
#include <iostream>

using namespace boost::spirit;
using namespace boost::spirit::ascii;

template<class Iterator>
struct sub_grammar_skipper: qi::grammar<Iterator>
{
    sub_grammar_skipper(): sub_grammar_skipper::base_type(start)
    {
        start =
            (
                *((char_ - eol) - lit(':')) >> lit(':') >> *blank >>
                    *(char_ - eol) >> eol
            )
        ;
    }

    qi::rule<Iterator> start;
};

template<class Iterator>
struct sub_grammar: qi::grammar<Iterator>
{
    sub_grammar(): sub_grammar::base_type(start)
    {
        string =
            (
                *(char_ - eol)
            )
        ;

        name %=
            (
                lit("NAME:") >> *blank >> string >> eol
            )
        ;

        start =
            (
                name
            )
        ;
    }

    qi::rule<Iterator, std::string()> string;

    qi::rule<Iterator, std::string()> name;

    qi::rule<Iterator> start;
};

template<class Iterator>
struct test_grammar: qi::grammar<Iterator/*, sub_grammar_skipper<Iterator> */>
{
    test_grammar(): test_grammar::base_type(start)
    {
        start =
            (
                sg >> int_
            )
        ;
    }

    sub_grammar<Iterator> sg;

    qi::rule<Iterator/*, sub_grammar_skipper<Iterator> */> start;
};

int main()
{
    std::string str("NAME: John\nBLAH: blah\n10");
    typedef std::string::const_iterator iterator;

    iterator first = str.begin();
    iterator last = str.end();

    test_grammar<iterator> tg;
    bool r = parse(first, last, tg);

    if(r && first == last)
    {
        std::cout << "Success!\n";
    }
    else
    {
        std::cerr << "Failed to parse at: " << std::string(first, last) <<
            std::endl;
        return 1;
    }

    return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net