1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // Copyright (c) 2011 Dean Michael Berries |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | #include <boost/spirit/include/qi.hpp> |
8 | |
9 | #include <boost/core/lightweight_test.hpp> |
10 | #include <boost/fusion/tuple.hpp> |
11 | #include <string> |
12 | |
13 | struct foo_parts |
14 | { |
15 | boost::optional<std::string> first; |
16 | std::string second; |
17 | }; |
18 | |
19 | namespace boost { namespace spirit { namespace traits |
20 | { |
21 | template <> |
22 | struct transform_attribute<foo_parts |
23 | , fusion::tuple<std::string &, optional<std::string> &> |
24 | , spirit::qi::domain> |
25 | { |
26 | typedef fusion::tuple<std::string&, optional<std::string>&> type; |
27 | |
28 | static type pre(foo_parts & parts) |
29 | { |
30 | return fusion::tie(arg&: parts.second, arg&: parts.first); |
31 | } |
32 | |
33 | static void post(foo_parts &, type const &) {} |
34 | static void fail(foo_parts &) {} |
35 | }; |
36 | }}} |
37 | |
38 | namespace qi = boost::spirit::qi; |
39 | |
40 | template <typename Iterator> |
41 | struct foo_grammar : qi::grammar<Iterator, foo_parts()> |
42 | { |
43 | foo_grammar() : foo_grammar::base_type(start, "foo" ) |
44 | { |
45 | foo_part = |
46 | +qi::alpha >> -(+qi::digit) |
47 | | qi::attr(std::string()) |
48 | >> qi::attr(boost::optional<std::string>()) |
49 | ; |
50 | |
51 | start = foo_part.alias(); |
52 | } |
53 | |
54 | typedef boost::fusion::tuple<std::string&, boost::optional<std::string>&> |
55 | tuple_type; |
56 | |
57 | qi::rule<Iterator, tuple_type()> foo_part; |
58 | qi::rule<Iterator, foo_parts()> start; |
59 | }; |
60 | |
61 | int main() |
62 | { |
63 | foo_parts instance; |
64 | foo_grammar<std::string::iterator> grammar; |
65 | std::string input = "abc123" ; |
66 | |
67 | BOOST_TEST(qi::parse(input.begin(), input.end(), grammar, instance) && |
68 | instance.first && instance.first.get() == "123" && |
69 | instance.second == "abc" ); |
70 | |
71 | return boost::report_errors(); |
72 | } |
73 | |
74 | |