]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/workbench/x3/toy/toy.cpp
4 #include <boost/mpl/identity.hpp>
6 namespace boost
{ namespace spirit
{ namespace x3
8 template <typename Derived
>
11 Derived
const& derived() const
13 return *static_cast<Derived
const*>(this);
17 template <typename Char
>
18 struct char_parser
: parser
<char_parser
<Char
>>
20 char_parser(Char ch
) : ch(ch
) {}
22 template <typename Iterator
, typename Context
>
23 bool parse(Iterator
& first
, Iterator last
, Context
const& ctx
) const
25 if (first
!= last
&& *first
== ch
)
36 template <typename Char
>
37 inline char_parser
<Char
> char_(Char ch
)
39 return char_parser
<Char
>(ch
);
42 template <typename Left
, typename Right
>
43 struct sequence_parser
: parser
<sequence_parser
<Left
, Right
>>
45 sequence_parser(Left left
, Right right
)
46 : left(left
), right(right
) {}
48 template <typename Iterator
, typename Context
>
49 bool parse(Iterator
& first
, Iterator last
, Context
const& ctx
) const
51 return left
.parse(first
, last
, ctx
)
52 && right
.parse(first
, last
, ctx
);
59 template <typename Left
, typename Right
>
60 inline sequence_parser
<Left
, Right
> operator>>(
61 parser
<Left
> const& left
, parser
<Right
> const& right
)
63 return sequence_parser
<Left
, Right
>(
64 left
.derived(), right
.derived());
67 template <typename Left
, typename Right
>
68 struct alternative_parser
: parser
<alternative_parser
<Left
, Right
>>
70 alternative_parser(Left left
, Right right
)
71 : left(left
), right(right
) {}
73 template <typename Iterator
, typename Context
>
74 bool parse(Iterator
& first
, Iterator last
, Context
const& ctx
) const
76 if (left
.parse(first
, last
, ctx
))
78 return right
.parse(first
, last
, ctx
);
85 template <typename Left
, typename Right
>
86 inline alternative_parser
<Left
, Right
> operator|(
87 parser
<Left
> const& left
, parser
<Right
> const& right
)
89 return alternative_parser
<Left
, Right
>(
90 left
.derived(), right
.derived());
93 template <typename ID
, typename T
, typename NextContext
>
96 context(T
const& val
, NextContext
const& next_ctx
)
97 : val(val
), next_ctx(next_ctx
) {}
99 T
const& get(mpl::identity
<ID
>) const
104 template <typename Identity
>
105 decltype(std::declval
<NextContext
>().get(Identity()))
106 get(Identity id
) const
108 return next_ctx
.get(id
);
112 NextContext
const& next_ctx
;
118 template <typename ID
>
119 undefined
get(ID
) const
125 template <typename ID
, typename RHS
>
126 struct rule_definition
: parser
<rule_definition
<ID
, RHS
>>
128 rule_definition(RHS rhs
)
131 template <typename Iterator
, typename Context
>
132 bool parse(Iterator
& first
, Iterator last
, Context
const& ctx
) const
134 context
<ID
, RHS
, Context
> this_ctx(rhs
, ctx
);
135 return rhs
.parse(first
, last
, this_ctx
);
141 template <typename ID
>
142 struct rule
: parser
<rule
<ID
>>
144 template <typename Derived
>
145 rule_definition
<ID
, Derived
>
146 operator=(parser
<Derived
> const& definition
) const
148 return rule_definition
<ID
, Derived
>(definition
.derived());
151 template <typename Iterator
, typename Context
>
152 bool parse(Iterator
& first
, Iterator last
, Context
const& ctx
) const
154 return ctx
.get(mpl::identity
<ID
>()).parse(first
, last
, ctx
);
158 template <typename Iterator
, typename Derived
>
159 inline bool parse(parser
<Derived
> const& p
, Iterator
& first
, Iterator last
)
162 return p
.derived().parse(first
, last
, ctx
);
167 ///////////////////////////////////////////////////////////////////////////////
170 template <typename Parser
>
171 bool test_parse(Parser
const& p
, char const* in
)
173 return parse(p
, in
, in
+ std::strlen(in
));
178 using namespace boost::spirit::x3
;
180 namespace g_definition
182 auto const x
= rule
<class x
>();
183 auto const ax
= char_('a') >> x
;
188 using g_definition::g
;
194 { // a non-recursive parser
195 using namespace boost::spirit::x3
;
197 auto abc
= char_('a') >> char_('b') >> char_('c');
198 std::cout
<< test_parse(abc
, "abc") << std::endl
;
199 std::cout
<< test_parse(abc
, "abx") << std::endl
;
200 std::cout
<< "==========================================" << std::endl
;
203 { // a recursive rule
204 using namespace boost::spirit::x3
;
206 auto const x
= rule
<class x
>();
207 auto const ax
= char_('a') >> x
;
208 auto const start
= (x
= char_('x') | ax
);
210 std::cout
<< test_parse(start
, "x") << std::endl
;
211 std::cout
<< test_parse(start
, "ax") << std::endl
;
212 std::cout
<< test_parse(start
, "aaaaax") << std::endl
;
213 std::cout
<< test_parse(start
, "aaz") << std::endl
;
214 std::cout
<< "==========================================" << std::endl
;
217 { // a grammar ( gcc and clang only: see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3582.html )
219 using namespace boost::spirit::x3
;
223 auto ax
= char_('a') >> x
;
224 return x
= char_('x') | ax
;
228 std::cout
<< test_parse(g
, "x") << std::endl
;
229 std::cout
<< test_parse(g
, "ax") << std::endl
;
230 std::cout
<< test_parse(g
, "aaaaax") << std::endl
;
231 std::cout
<< test_parse(g
, "aaz") << std::endl
;
232 std::cout
<< "==========================================" << std::endl
;
235 { // another grammar using namespaces (standard c++, see grammar g definition above in namespace parser.)
238 std::cout
<< test_parse(g
, "x") << std::endl
;
239 std::cout
<< test_parse(g
, "ax") << std::endl
;
240 std::cout
<< test_parse(g
, "aaaaax") << std::endl
;
241 std::cout
<< test_parse(g
, "aaz") << std::endl
;
242 std::cout
<< "==========================================" << std::endl
;