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 the steps needed to integrate a custom container
7 // type to be usable with Spirit.Qi. It shows how to utilize the QString data
8 // type as a Qi attribute.
9
10 // Note: you need to have Qt4 installed on your system and you have to make
11 // sure your compiler finds the includes and your linker finds the
12 // proper libraries.
13
14 #include <boost/config/warning_disable.hpp>
15 #include <boost/spirit/include/qi.hpp>
16
17 #include <Qt/qstring.h>
18
19 namespace boost { namespace spirit { namespace traits
20 {
21 // Make Qi recognize QString as a container
22 template <> struct is_container<QString> : mpl::true_ {};
23
24 // Expose the container's (QString's) value_type
25 template <> struct container_value<QString> : mpl::identity<QChar> {};
26
27 // Define how to insert a new element at the end of the container (QString)
28 template <>
29 struct push_back_container<QString, QChar>
30 {
callboost::spirit::traits::push_back_container31 static bool call(QString& c, QChar const& val)
32 {
33 c.append(val);
34 return true;
35 }
36 };
37
38 // Test if a QString is empty (required for debug)
39 template <>
40 struct is_empty_container<QString>
41 {
callboost::spirit::traits::is_empty_container42 static bool call(QString const& c)
43 {
44 return c.isEmpty();
45 }
46 };
47
48 // Define how to stream a QString (required for debug)
49 template <typename Out, typename Enable>
50 struct print_attribute_debug<Out, QString, Enable>
51 {
callboost::spirit::traits::print_attribute_debug52 static void call(Out& out, QString const& val)
53 {
54 out << val.toStdString();
55 }
56 };
57 }}}
58
59 ///////////////////////////////////////////////////////////////////////////////
60 namespace client
61 {
62 template <typename Iterator>
parse_qstring(Iterator first,Iterator last,QString & t)63 bool parse_qstring(Iterator first, Iterator last, QString& t)
64 {
65 using boost::spirit::qi::char_;
66 using boost::spirit::ascii::space;
67 using boost::spirit::qi::phrase_parse;
68
69 bool r = phrase_parse(first, last, +char_, space, t);
70 if (!r || first != last) // fail if we did not get a full match
71 return false;
72
73 return r;
74 }
75 }
76
77 ///////////////////////////////////////////////////////////////////////////////
main()78 int main()
79 {
80 std::cout << "/////////////////////////////////////////////////////////\n\n";
81 std::cout << "\t\tParsing into a QString from Spirit...\n\n";
82 std::cout << "/////////////////////////////////////////////////////////\n\n";
83
84 std::cout << "Give me a complex number of the form r or (r) or (r,i) \n";
85 std::cout << "Type [q or Q] to quit\n\n";
86
87 std::string str;
88 while (getline(std::cin, str))
89 {
90 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
91 break;
92
93 QString t;
94 if (client::parse_qstring(str.begin(), str.end(), t))
95 {
96 std::cout << "-------------------------\n";
97 std::cout << "Parsing succeeded\n";
98 std::cout << "got: " << t.toStdString() << std::endl;
99 std::cout << "\n-------------------------\n";
100 }
101 else
102 {
103 std::cout << "-------------------------\n";
104 std::cout << "Parsing failed\n";
105 std::cout << "-------------------------\n";
106 }
107 }
108
109 std::cout << "Bye... :-) \n\n";
110 return 0;
111 }
112
113
114