]>
Commit | Line | Data |
---|---|---|
1 | [#foldl_start_with_parser] | |
2 | [section foldl_start_with_parser] | |
3 | ||
4 | [h1 Synopsis] | |
5 | ||
6 | template <class P, class StateP, class ForwardOp> | |
7 | struct foldl_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 | [[`ForwardOp`] [[link metafunction_class template metafunction class] taking two arguments]] | |
16 | ] | |
17 | ||
18 | [h1 Description] | |
19 | ||
20 | The same as [link foldl `foldl`], but before folding it applies a parser, | |
21 | `StateP` on the input. If it fails, `foldl_start_with_parser` fails. If it | |
22 | succeeds, `foldl_start_with_parser` works as `foldl` taking the result of | |
23 | `StateP` as the initial state. | |
24 | ||
25 | Here is a diagram showing how `foldl_start_with_parser` works by example: | |
26 | ||
27 | using int_token = token<int_>; | |
28 | using plus_token = token<lit_c<'+'>>; | |
29 | using plus_int = last_of<plus_token, int_token>; | |
30 | using sum_op = mpl::lambda<mpl::plus<mpl::_1, mpl::_2>>::type; | |
31 | ||
32 | [$images/metaparse/foldl_start_with_parser_diag1.png [width 70%]] | |
33 | ||
34 | Further details can be found in the | |
35 | [link introducing-foldl_start_with_parser Introducing foldl_start_with_parser] | |
36 | section of the [link manual User Manual]. | |
37 | ||
38 | [h1 Header] | |
39 | ||
40 | #include <boost/metaparse/foldl_start_with_parser.hpp> | |
41 | ||
42 | [h1 Expression semantics] | |
43 | ||
44 | For any `p` parser, `pt` class, `f` metafunction class taking two arguments, | |
45 | `s` compile-time string and `pos` source position | |
46 | ||
47 | foldl_start_with_parser<p, pt, f>::apply<s, pos> | |
48 | ||
49 | is equivalent to | |
50 | ||
51 | pt::apply<s, pos> | |
52 | ||
53 | when the above expression returns a parsing error. It is | |
54 | ||
55 | foldl<p, get_result<pt::apply<s, pos>>::type, f>::apply< | |
56 | get_remaining<pt::apply<s, pos>>::type, | |
57 | get_position<pt::apply<s, pos>>::type | |
58 | > | |
59 | ||
60 | otherwise. | |
61 | ||
62 | [h1 Example] | |
63 | ||
64 | #include <boost/metaparse/foldl_start_with_parser.hpp> | |
65 | #include <boost/metaparse/lit_c.hpp> | |
66 | #include <boost/metaparse/last_of.hpp> | |
67 | #include <boost/metaparse/token.hpp> | |
68 | #include <boost/metaparse/int_.hpp> | |
69 | #include <boost/metaparse/string.hpp> | |
70 | #include <boost/metaparse/start.hpp> | |
71 | #include <boost/metaparse/get_result.hpp> | |
72 | #include <boost/metaparse/is_error.hpp> | |
73 | ||
74 | #include <boost/mpl/lambda.hpp> | |
75 | #include <boost/mpl/plus.hpp> | |
76 | ||
77 | using namespace boost::metaparse; | |
78 | ||
79 | using int_token = token<int_>; | |
80 | using plus_token = token<lit_c<'+'>>; | |
81 | using plus_int = last_of<plus_token, int_token>; | |
82 | using sum_op = | |
83 | boost::mpl::lambda<boost::mpl::plus<boost::mpl::_1, boost::mpl::_2>>::type; | |
84 | ||
85 | using ints = foldl_start_with_parser<plus_int, int_token, sum_op>; | |
86 | ||
87 | static_assert( | |
88 | get_result< | |
89 | ints::apply<BOOST_METAPARSE_STRING("11 + 13 + 3 + 21"), start> | |
90 | >::type::value == 48, | |
91 | "ints should sum the numbers" | |
92 | ); | |
93 | ||
94 | static_assert( | |
95 | is_error<ints::apply<BOOST_METAPARSE_STRING(""), start>>::type::value, | |
96 | "when no numbers are provided, it should be an error" | |
97 | ); | |
98 | ||
99 | [endsect] | |
100 |