]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2001-2010 Hartmut Kaiser |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | // This example demonstrates a trick allowing to adapt a template data | |
7 | // structure as a Fusion sequence in order to use is for direct attribute | |
8 | // propagation. For more information see | |
9 | // http://boost-spirit.com/home/2010/02/08/how-to-adapt-templates-as-a-fusion-sequence | |
10 | ||
11 | #include <boost/spirit/include/qi.hpp> | |
12 | ||
13 | namespace qi = boost::spirit::qi; | |
14 | namespace fusion = boost::fusion; | |
15 | ||
16 | namespace client | |
17 | { | |
18 | template <typename A, typename B> | |
19 | struct data | |
20 | { | |
21 | A a; | |
22 | B b; | |
23 | }; | |
24 | ||
25 | template <typename Iterator, typename A, typename B> | |
26 | struct data_grammar : qi::grammar<Iterator, data<A, B>()> | |
27 | { | |
28 | data_grammar() : data_grammar::base_type(start) | |
29 | { | |
30 | start = real_start; | |
31 | real_start = qi::auto_ >> ',' >> qi::auto_; | |
32 | } | |
33 | ||
34 | qi::rule<Iterator, data<A, B>()> start; | |
35 | qi::rule<Iterator, fusion::vector<A&, B&>()> real_start; | |
36 | }; | |
37 | } | |
38 | ||
39 | namespace boost { namespace spirit { namespace traits | |
40 | { | |
41 | template <typename A, typename B> | |
42 | struct transform_attribute<client::data<A, B>, fusion::vector<A&, B&>, qi::domain> | |
43 | { | |
44 | typedef fusion::vector<A&, B&> type; | |
45 | ||
46 | static type pre(client::data<A, B>& val) { return type(val.a, val.b); } | |
47 | static void post(client::data<A, B>&, fusion::vector<A&, B&> const&) {} | |
48 | static void fail(client::data<A, B>&) {} | |
49 | }; | |
50 | }}} | |
51 | ||
52 | /////////////////////////////////////////////////////////////////////////////// | |
53 | int main() | |
54 | { | |
55 | std::cout << "/////////////////////////////////////////////////////////\n\n"; | |
56 | std::cout << "\t\tA parser for Spirit utilizing an adapted template ...\n\n"; | |
57 | std::cout << "/////////////////////////////////////////////////////////\n\n"; | |
58 | ||
59 | std::cout << "Give me two comma separated integers:\n"; | |
60 | std::cout << "Type [q or Q] to quit\n\n"; | |
61 | ||
62 | std::string str; | |
63 | client::data_grammar<std::string::const_iterator, long, int> g; // Our grammar | |
64 | while (getline(std::cin, str)) | |
65 | { | |
66 | if (str.empty() || str[0] == 'q' || str[0] == 'Q') | |
67 | break; | |
68 | ||
69 | client::data<long, int> d; | |
70 | std::string::const_iterator iter = str.begin(); | |
71 | std::string::const_iterator end = str.end(); | |
72 | bool r = phrase_parse(iter, end, g, qi::space, d); | |
73 | ||
74 | if (r && iter == end) | |
75 | { | |
76 | std::cout << "-------------------------\n"; | |
77 | std::cout << "Parsing succeeded\n"; | |
78 | std::cout << "got: " << d.a << "," << d.b << std::endl; | |
79 | std::cout << "\n-------------------------\n"; | |
80 | } | |
81 | else | |
82 | { | |
83 | std::cout << "-------------------------\n"; | |
84 | std::cout << "Parsing failed\n"; | |
85 | std::cout << "-------------------------\n"; | |
86 | } | |
87 | } | |
88 | ||
89 | return 0; | |
90 | } | |
91 | ||
92 |