• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2002-2010 Joel de Guzman
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 ///////////////////////////////////////////////////////////////////////////////
8 //
9 //  A parser for arbitrary tuples. This example presents a parser
10 //  for an employee structure.
11 //
12 //  [ JDG May 9, 2007 ]
13 //
14 ///////////////////////////////////////////////////////////////////////////////
15 
16 #include <boost/config/warning_disable.hpp>
17 #include <boost/spirit/include/qi.hpp>
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_operator.hpp>
20 #include <boost/spirit/include/phoenix_object.hpp>
21 #include <boost/fusion/include/adapt_struct.hpp>
22 #include <boost/fusion/include/io.hpp>
23 
24 #include <iostream>
25 #include <string>
26 #include <complex>
27 
28 namespace client
29 {
30     namespace qi = boost::spirit::qi;
31     namespace ascii = boost::spirit::ascii;
32 
33     ///////////////////////////////////////////////////////////////////////////
34     //  Our employee struct
35     ///////////////////////////////////////////////////////////////////////////
36     //[tutorial_employee_struct
37     struct employee
38     {
39         int age;
40         std::string surname;
41         std::string forename;
42         double salary;
43     };
44     //]
45 }
46 
47 // We need to tell fusion about our employee struct
48 // to make it a first-class fusion citizen. This has to
49 // be in global scope.
50 
51 //[tutorial_employee_adapt_struct
52 BOOST_FUSION_ADAPT_STRUCT(
53     client::employee,
54     (int, age)
55     (std::string, surname)
56     (std::string, forename)
57     (double, salary)
58 )
59 //]
60 
61 namespace client
62 {
63     ///////////////////////////////////////////////////////////////////////////////
64     //  Our employee parser
65     ///////////////////////////////////////////////////////////////////////////////
66     //[tutorial_employee_parser
67     template <typename Iterator>
68     struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>
69     {
employee_parserclient::employee_parser70         employee_parser() : employee_parser::base_type(start)
71         {
72             using qi::int_;
73             using qi::lit;
74             using qi::double_;
75             using qi::lexeme;
76             using ascii::char_;
77 
78             quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
79 
80             start %=
81                 lit("employee")
82                 >> '{'
83                 >>  int_ >> ','
84                 >>  quoted_string >> ','
85                 >>  quoted_string >> ','
86                 >>  double_
87                 >>  '}'
88                 ;
89         }
90 
91         qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
92         qi::rule<Iterator, employee(), ascii::space_type> start;
93     };
94     //]
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////
98 //  Main program
99 ////////////////////////////////////////////////////////////////////////////
100 int
main()101 main()
102 {
103     std::cout << "/////////////////////////////////////////////////////////\n\n";
104     std::cout << "\t\tAn employee parser for Spirit...\n\n";
105     std::cout << "/////////////////////////////////////////////////////////\n\n";
106 
107     std::cout
108         << "Give me an employee of the form :"
109         << "employee{age, \"surname\", \"forename\", salary } \n";
110     std::cout << "Type [q or Q] to quit\n\n";
111 
112     using boost::spirit::ascii::space;
113     typedef std::string::const_iterator iterator_type;
114     typedef client::employee_parser<iterator_type> employee_parser;
115 
116     employee_parser g; // Our grammar
117     std::string str;
118     while (getline(std::cin, str))
119     {
120         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
121             break;
122 
123         client::employee emp;
124         std::string::const_iterator iter = str.begin();
125         std::string::const_iterator end = str.end();
126         bool r = phrase_parse(iter, end, g, space, emp);
127 
128         if (r && iter == end)
129         {
130             std::cout << boost::fusion::tuple_open('[');
131             std::cout << boost::fusion::tuple_close(']');
132             std::cout << boost::fusion::tuple_delimiter(", ");
133 
134             std::cout << "-------------------------\n";
135             std::cout << "Parsing succeeded\n";
136             std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl;
137             std::cout << "\n-------------------------\n";
138         }
139         else
140         {
141             std::cout << "-------------------------\n";
142             std::cout << "Parsing failed\n";
143             std::cout << "-------------------------\n";
144         }
145     }
146 
147     std::cout << "Bye... :-) \n\n";
148     return 0;
149 }
150 
151 
152