]>
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 | // The main purpose of this example is to show how a single fusion sequence | |
7 | // can be filled from a parsed input of the elements in different sequences | |
8 | ||
7c673cae FG |
9 | #include <boost/spirit/include/qi.hpp> |
10 | #include <boost/fusion/include/struct.hpp> | |
11 | #include <boost/fusion/include/nview.hpp> | |
12 | #include <boost/foreach.hpp> | |
13 | ||
14 | namespace fusion = boost::fusion; | |
15 | namespace qi = boost::spirit::qi; | |
16 | ||
17 | /////////////////////////////////////////////////////////////////////////////// | |
18 | namespace client | |
19 | { | |
20 | // Our employee struct | |
21 | struct employee | |
22 | { | |
23 | std::string surname; | |
24 | std::string forename; | |
25 | int age; | |
26 | double salary; | |
27 | std::string department; | |
28 | }; | |
29 | ||
30 | // define iterator type | |
31 | typedef std::string::const_iterator iterator_type; | |
32 | ||
33 | // This is the output routine taking a format description and the data to | |
34 | ||
35 | template <typename Parser, typename Sequence> | |
36 | bool parse(std::string const& input, Parser const& p, Sequence& s) | |
37 | { | |
38 | iterator_type begin = input.begin(); | |
39 | return qi::parse(begin, input.end(), p, s); | |
40 | } | |
41 | } | |
42 | ||
43 | // We need to tell fusion about our employee struct to make it a first-class | |
44 | // fusion citizen. This has to be in global scope. Note that we don't need to | |
45 | // list the members of our struct in the same sequence a they are defined | |
46 | BOOST_FUSION_ADAPT_STRUCT( | |
47 | client::employee, | |
48 | (int, age) | |
49 | (std::string, surname) | |
50 | (std::string, forename) | |
51 | (std::string, department) | |
52 | (double, salary) | |
53 | ) | |
54 | ||
55 | /////////////////////////////////////////////////////////////////////////////// | |
56 | // that's the different types we need to reorder the attributes | |
57 | typedef fusion::result_of::as_nview<client::employee, 2, 0>::type name_and_age; | |
58 | typedef fusion::result_of::as_nview<client::employee, 1, 2, 4>::type names_and_salary; | |
59 | typedef fusion::result_of::as_nview<client::employee, 2, 0, 3>::type name_age_and_department; | |
60 | ||
61 | /////////////////////////////////////////////////////////////////////////////// | |
62 | int main() | |
63 | { | |
64 | std::string str; | |
65 | ||
66 | // some employees | |
67 | client::employee john; | |
68 | client::employee mary; | |
69 | client::employee tom; | |
70 | ||
71 | // print data about employees in different formats | |
72 | { | |
73 | // parse forename and age only | |
74 | name_and_age johnview(fusion::as_nview<2, 0>(john)); | |
75 | bool r = client::parse( | |
76 | "John, 25", | |
77 | *(qi::char_ - ',') >> ", " >> qi::int_, | |
78 | johnview); | |
79 | if (r) { | |
80 | std::cout << "Parsed: " << john.forename << ", " << john.age | |
81 | << std::endl; | |
82 | } | |
83 | ||
84 | // parse surname, forename, and salary | |
85 | names_and_salary maryview(fusion::as_nview<1, 2, 4>(mary)); | |
86 | r = client::parse( | |
87 | "Higgins, Mary: 2200.36", | |
88 | *(qi::char_ - ',') >> ", " >> *(qi::char_ - ':') >> ": " >> qi::double_, | |
89 | maryview); | |
90 | if (r) { | |
91 | std::cout << "Parsed: " << mary.forename << ", " << mary.surname | |
92 | << ", " << mary.salary << std::endl; | |
93 | } | |
94 | ||
95 | // parse forename, age, and department | |
96 | name_age_and_department tomview(fusion::as_nview<2, 0, 3>(tom)); | |
97 | client::parse( | |
98 | "Tom: 48 (Boss)", | |
99 | *(qi::char_ - ':') >> ": " >> qi::int_ >> " (" >> *(qi::char_ - ')') >> ')', | |
100 | tomview); | |
101 | if (r) { | |
102 | std::cout << "Parsed: " << tom.forename << ", " << tom.age | |
103 | << ", " << tom.department << std::endl; | |
104 | } | |
105 | } | |
106 | ||
107 | // now parse a list of several employees and print them all | |
108 | std::vector<client::employee> employees; | |
109 | ||
110 | // parse surname, forename, and salary for all employees | |
111 | { | |
112 | qi::rule<client::iterator_type, names_and_salary()> r = | |
113 | *(qi::char_ - ',') >> ", " >> *(qi::char_ - ',') >> ", " >> qi::double_; | |
114 | ||
115 | bool result = client::parse( | |
116 | "John, Smith, 2000.50\n" "Mary, Higgins, 2200.36\n" "Tom, Taylor, 3200.00\n", | |
117 | r % qi::eol, employees); | |
118 | ||
119 | std::cout << "Parsed: " << std::endl; | |
120 | BOOST_FOREACH(client::employee const& e, employees) | |
121 | { | |
122 | std::cout << e.forename << ", " << e.surname << ", " << e.salary | |
123 | << std::endl; | |
124 | } | |
125 | } | |
126 | return 0; | |
127 | } | |
128 |