Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
5.2.3. Using a folding parser combinator
[Note] Note

Note that you can find everything that has been included and defined so far here.

It would be nice, if the two loops could be merged together and the temporary vector wouldn't have to be built in the middle (don't forget: there is no such thing as a garbage collector for template metaprogramming. Once you instantiate a template, it will be available until the end of ... the compilation).

Metaparse provides the foldl parser combinator:

> #include <boost/metaparse/foldl.hpp>

It is almost the same as boost::mpl::fold, but instead of taking the vector as its first argument, which was coming from the repeated application of a parser (sequence<plus_token, int_token>) on the input, it takes the parser itself. foldl parses the input and calculates the summary on the fly. Here is how we can write our parser using it:

> using exp_parser10 = \
...> build_parser< \
...>   transform< \
...>     sequence< \
...>       int_token, \
...>       foldl< \
...>         sequence<plus_token, int_token>, \
...>         boost::mpl::int_<0>, \
...>         boost::mpl::quote2<sum_items> \
...>       > \
...>     >, \
...>     boost::mpl::quote1<sum_vector>> \
...> >;

copy-paste friendly version

Here are the formatted versions of exp_parser9 and exp_parser10 side-by-side:

//            exp_parser9                                       exp_parser10

build_parser<                                       build_parser<
  transform<                                          transform<
    sequence<                                           sequence<
      int_token,                                          int_token,


      transform<                                          foldl<
        repeated<sequence<plus_token, int_token>>,          sequence<plus_token, int_token>,
        boost::mpl::lambda<
          boost::mpl::fold<
            boost::mpl::_1,
            boost::mpl::int_<0>,                            boost::mpl::int_<0>,
            boost::mpl::quote2<sum_items>                   boost::mpl::quote2<sum_items>
          >
        >::type
      >                                                   >


    >,                                                  >,
    boost::mpl::quote1<sum_vector>                      boost::mpl::quote1<sum_vector>
  >                                                   >
>                                                   >

copy-paste friendly version

In exp_parser10 the "_repeated and then transform with boost::mpl::fold_" part (the middle block of exp_parser9) has been replaced by one foldl parser that does the same thing but without building a vector in the middle. The same starting value (boost::mpl::int_<0>) and callback function (sum_items) could be used.

Here is a diagram showing how exp_parser10 works:

In this case, the results of the sequence<plus_token, int_token> parsers are passed directly to a folding algorithm without an intermediate vector. Here is a diagram showing exp_parser9 and exp_parser10 side-by-side to make it easier to see the difference:


PrevUpHomeNext