Home | Libraries | People | FAQ | More |
Note | |
---|---|
Note that you can find everything that has been included and defined so far here. |
It would be nice if we could evaluate the expression as well. Instead of
returning a vector
as the
result of parsing, we should return the evaluated expression. For example
the result of parsing "11 + 2"
should be mpl_::integral_c<int, 13>
.
Metaparse provides transform
which we can use to implement this:
> #include <boost/metaparse/transform.hpp>
This can be used to transform the result of a parser. For example we have
the sequence
<int_token, plus_token, int_token>
parser which returns a vector
. We want to transform this vector
into a number, which is the result
of evaluating the expression. We need to pass transform
the sequence
<...>
parser and a function which turns the vector
into the result we need. First let's create this metafunction:
> #include <boost/mpl/plus.hpp> > #include <boost/mpl/at.hpp> > template <class Vector> \ ...> struct eval_plus : \ ...> boost::mpl::plus< \ ...> typename boost::mpl::at_c<Vector, 0>::type, \ ...> typename boost::mpl::at_c<Vector, 2>::type \ ...> > {};
Note | |
---|---|
Note that if the last character of your command is the |
What it does is that using boost::mpl::at_c
it takes the first (index 0) and the third (index 2) elements of the vector
that is the result of parsing
with sequence
<...>
and adds them. We can try it
out with an example vector
:
> eval_plus< \ ...> boost::mpl::vector< \ ...> mpl_::integral_c<int, 11>, \ ...> mpl_::char_<'+'>, \ ...> mpl_::integral_c<int, 2> \ ...> >>::type mpl_::integral_c<int, 13>
We can use eval_plus
to
build a parser that evaluates the expression it parses:
> #include <boost/mpl/quote.hpp> > using exp_parser6 = \ ...> build_parser< \ ...> transform< \ ...> sequence<int_token, plus_token, int_token>, \ ...> boost::mpl::quote1<eval_plus> \ ...> > \ ...> >;
Note | |
---|---|
Note that we have to use |
transform
parses the input using sequence
<int_token, plus_token, int_token>
and transforms the result of that using
eval_plus
. Let's try it
out:
> exp_parser6::apply<BOOST_METAPARSE_STRING("11 + 2")>::type mpl_::integral_c<int, 13>
We have created a simple expression parser. The following diagram shows how it works:
The rounded boxes in the diagram are the parsers parsing the input, which are functions (template metafunction classes). The arrows represent how the results are passed around between these parsers (they are the return values of the function calls).
It uses sequence
to parse the different elements (the first number, the +
symbol and the second number) and builds a vector
.
The final result is calculated from that vector
by the transform
parser.