Qi flush_multi_pass parser

| Home | Libraries | People | FAQ | More

#### Qi flush_multi_pass parser

###### Description

The Spirit.Qi `flush_multi_pass` parser is a primitive (pseudo) parser component allowing to clear the internal buffer of a `multi_pass` iterator. Clearing the buffer of a `multi_pass` might be beneficial for grammars where it is clear that no backtracking can occur. The general syntax for using the `flush_multi_pass` is:

    flush_multi_pass

which will call the `clear_queue()` member function if the current iterators are of the type `multi_pass`. This will cause any buffered data to be erased. This also will invalidate all other copies of multi_pass and they should not be used. If they are, an `boost::illegal_backtracking` exception will be thrown. For all other iterator types this is a no-op. The `flush_multi_pass` generates a parser component which always succeeds and which does not consume any input (very much like `eps`).

###### Header

    // forwards to <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp>
    #include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>

###### Synopsis

    flush_multi_pass

###### Parameters

The `flush_multi_pass` does not require any parameters.

###### Attribute

The `flush_multi_pass` component exposes no attribute (the exposed attribute type is `unused_type`):

    flush_multi_pass --> unused

###### Example

The following example shows a simple use case of the `flush_multi_pass` parser.

We will illustrate its usage by generating different comment styles and a function prototype (for the full example code see here: flush_multi_pass.cpp)

###### Prerequisites

In addition to the main header file needed to include the core components implemented in Spirit.Qi we add the header file needed for the new `flush_multi_pass` parser.

    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>

To make all the code below more readable we introduce the following namespaces.

    namespace spirit = boost::spirit;
    using boost::spirit::repository::flush_multi_pass;

###### Clearing the internal buffer

The example grammar recognizes the (simplified) preprocessor commands `#define` and `#undef` both of which are constraint to a single line. This makes it possible to delete all internal iterator buffers on each detected line break. This is safe as no backtracking will occur after any line end. The following code snippet shows the usage of `flush_multi_pass` for this purpose.

    template <typename Iterator, typename Skipper>
    struct preprocessor : spirit::qi::grammar<Iterator, Skipper>
    {
        // This is a simplified preprocessor grammar recognizing
        //
        //   #define MACRONAME something
        //   #undef MACRONAME
        //
        // Its sole purpose is to show an example how to use the
        // flush_multi_pass parser. At the end of each line no backtracking can
        // occur anymore so that it's safe to clear all internal buffers in the
        // multi_pass.
        preprocessor() : preprocessor::base_type(file)
        {
            using spirit::ascii::char_;
            using spirit::qi::eol;
            using spirit::qi::lit;

            file =
                *line
                ;

            line =  ( command |  *(char_ - eol) )
                >>  eol
                >>  flush_multi_pass
                ;

            command =
                    "#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol)
                |   "#undef"  >> *lit(' ') >> *(char_ - eol)
                ;
        }

        spirit::qi::rule<Iterator, Skipper> file, line, command;
    };

| Note
Using the `flush_multi_pass` parser component with iterators other than `multi_pass` is safe as it has no effect on the parsing.