...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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
).
// forwards to <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp> #include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>
flush_multi_pass
The flush_multi_pass
does
not require any parameters.
The flush_multi_pass
component
exposes no attribute (the exposed attribute type is unused_type
):
flush_multi_pass --> unused
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)
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;
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 |