]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [#foldr_start_with_parser] |
2 | [section foldr_start_with_parser] | |
3 | ||
4 | [h1 Synopsis] | |
5 | ||
6 | template <class P, class StateP, class BackwardOp> | |
7 | struct foldr_start_with_parser; | |
8 | ||
9 | This is a [link parser_combinator parser combinator]. | |
10 | ||
11 | [table Arguments | |
12 | [[Name] [Type]] | |
13 | [[`P`] [[link parser parser]]] | |
14 | [[`StateP`] [[link parser parser]]] | |
15 | [[`BackwardOp`] [[link metafunction_class template metafunction class] taking two arguments]] | |
16 | ] | |
17 | ||
18 | [h1 Description] | |
19 | ||
20 | The same as [link foldr `foldr`], but after folding it applies a parser, | |
21 | `StateP` on the input. If `StateP` fails, `foldr_start_with_parser` fails. If it | |
22 | succeeds, the result of parsing is equivalent to | |
23 | `boost::reverse_fold<Sequence, State, BackwardOp>`, where `Sequence` is the | |
24 | sequence of the results of the applications of `P` and `State` is the result | |
25 | `StateP` returned ['after] the repeated application of `P` on the input. | |
26 | ||
27 | Here is a diagram showing how `foldr_start_with_parser` works by example: | |
28 | ||
29 | using int_token = token<int_>; | |
30 | using plus_token = token<lit_c<'+'>>; | |
31 | using int_plus = first_of<int_token, plus_token>; | |
32 | using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type; | |
33 | ||
34 | [$images/metaparse/foldr_start_with_parser_diag1.png [width 70%]] | |
35 | ||
36 | Further details can be found in the | |
37 | [link introducing-foldr_start_with_parser Introducing foldr_start_with_parser] | |
38 | section of the [link manual User Manual]. | |
39 | ||
40 | [h1 Header] | |
41 | ||
42 | #include <boost/metaparse/foldr_start_with_parser.hpp> | |
43 | ||
44 | [h1 Expression semantics] | |
45 | ||
46 | For any `p` parser, `pt` class, `f` metafunction class taking two arguments, | |
47 | `s` compile-time string and `pos` source position let `pos_` be the position | |
48 | where the repeated application of `p` on `s` fails for the first time. Let | |
49 | `s_` be the postfix of `s` starting at that position. | |
50 | ||
51 | foldr_start_with_parser<p, pt, f>::apply<s, pos> | |
52 | ||
53 | is equivalent to | |
54 | ||
55 | pt::apply<s_, pos_> | |
56 | ||
57 | when the above expression returns a parsing error. It is | |
58 | ||
59 | return_< | |
60 | foldr<p, get_result<pt::apply<s_, pos_>>::type, f>::apply<s, pos> | |
61 | >::apply< | |
62 | get_remaining<pt::apply<s_, pos_>>::type, | |
63 | get_position<pt::apply<s_, pos_>>::type | |
64 | > | |
65 | ||
66 | otherwise. | |
67 | ||
68 | [h1 Example] | |
69 | ||
70 | #include <boost/metaparse/foldr_start_with_parser.hpp> | |
71 | #include <boost/metaparse/lit_c.hpp> | |
72 | #include <boost/metaparse/first_of.hpp> | |
73 | #include <boost/metaparse/token.hpp> | |
74 | #include <boost/metaparse/int_.hpp> | |
75 | #include <boost/metaparse/string.hpp> | |
76 | #include <boost/metaparse/start.hpp> | |
77 | #include <boost/metaparse/get_result.hpp> | |
78 | #include <boost/metaparse/is_error.hpp> | |
79 | ||
80 | #include <boost/mpl/lambda.hpp> | |
81 | #include <boost/mpl/plus.hpp> | |
82 | ||
83 | using namespace boost::metaparse; | |
84 | ||
85 | using int_token = token<int_>; | |
86 | using plus_token = token<lit_c<'+'>>; | |
87 | using int_plus = first_of<int_token, plus_token>; | |
88 | using sum_op = | |
89 | boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; | |
90 | ||
91 | using ints = foldr_start_with_parser<int_plus, int_token, sum_op>; | |
92 | ||
93 | static_assert( | |
94 | get_result< | |
95 | ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 + 21"), start> | |
96 | >::type::value == 48, | |
97 | "ints should sum the numbers" | |
98 | ); | |
99 | ||
100 | static_assert( | |
101 | is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, | |
102 | "when no numbers are provided, it should be an error" | |
103 | ); | |
104 | ||
105 | [endsect] | |
106 |