1// Copyright (c) 2001-2011 Hartmut Kaiser
2// Copyright (c) 2001-2011 Joel de Guzman
3// Copyright (c) 2010 Bryce Lelbach
4//
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#include <boost/spirit/include/qi.hpp>
9#include <boost/spirit/include/support_utree.hpp>
10
11#include <sstream>
12
13#include "test.hpp"
14
15inline bool check(boost::spirit::utree const& val, std::string expected)
16{
17 std::stringstream s;
18 s << val;
19 if (s.str() == expected + " ")
20 return true;
21
22 std::cerr << "got result: " << s.str()
23 << ", expected: " << expected << std::endl;
24 return false;
25}
26
27int main()
28{
29 using spirit_test::test_attr;
30 using boost::spirit::utree;
31 using boost::spirit::utree_type;
32 using boost::spirit::utf8_string_range_type;
33 using boost::spirit::utf8_symbol_type;
34 using boost::spirit::utf8_string_type;
35
36 using boost::spirit::qi::real_parser;
37 using boost::spirit::qi::strict_real_policies;
38 using boost::spirit::qi::digit;
39 using boost::spirit::qi::char_;
40 using boost::spirit::qi::string;
41 using boost::spirit::qi::int_;
42 using boost::spirit::qi::double_;
43 using boost::spirit::qi::space;
44 using boost::spirit::qi::space_type;
45 using boost::spirit::qi::rule;
46 using boost::spirit::qi::as;
47 using boost::spirit::qi::lexeme;
48
49 // primitive data types
50 {
51 utree ut;
52 BOOST_TEST(test_attr("x", char_, ut) &&
53 ut.which() == utree_type::string_type && check(ut, "\"x\""));
54 ut.clear();
55 BOOST_TEST(test_attr("123", int_, ut) &&
56 ut.which() == utree_type::int_type && check(ut, "123"));
57 ut.clear();
58 BOOST_TEST(test_attr("123.45", double_, ut) &&
59 ut.which() == utree_type::double_type && check(ut, "123.45"));
60 ut.clear();
61
62 rule<char const*, utf8_string_type()> r1 = lexeme[*char_];
63
64 BOOST_TEST(test_attr("foo", r1, ut) &&
65 ut.which() == utree_type::string_type && check(ut, "\"foo\""));
66 ut.clear();
67
68 rule<char const*, utf8_symbol_type()> r2 = lexeme[*char_];
69
70 BOOST_TEST(test_attr("xyz", r2, ut) &&
71 ut.which() == utree_type::symbol_type && check(ut, "xyz"));
72 }
73
74 // single character parsers
75 {
76 utree ut;
77
78 // this rule returns a utree string
79 rule<char const*, utree()> r1 = char_("abc");
80
81 // this rule forces a utree list to be returned
82 rule<char const*, utree::list_type()> r2 = char_("abc");
83
84 BOOST_TEST(test_attr("a", r1, ut) &&
85 ut.which() == utree_type::string_type && check(ut, "\"a\""));
86 ut.clear();
87 BOOST_TEST(test_attr("a", r2, ut) &&
88 ut.which() == utree_type::list_type && check(ut, "( \"a\" )"));
89 }
90
91 // sequences
92 {
93 using boost::spirit::qi::as_string;
94
95 utree ut;
96 BOOST_TEST(test_attr("xy", char_ >> char_, ut) &&
97 ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )"));
98 ut.clear();
99 BOOST_TEST(test_attr("123 456", int_ >> int_, ut, space) &&
100 ut.which() == utree_type::list_type && check(ut, "( 123 456 )"));
101 ut.clear();
102 BOOST_TEST(test_attr("1.23 4.56", double_ >> double_, ut, space) &&
103 ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )"));
104 ut.clear();
105 BOOST_TEST(test_attr("1.2ab", double_ >> *char_, ut) &&
106 ut.which() == utree_type::list_type && check(ut, "( 1.2 \"a\" \"b\" )"));
107 ut.clear();
108 BOOST_TEST(test_attr("ab1.2", *~digit >> double_, ut) &&
109 ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
110
111 // forces a utree list
112 rule<char const*, utree::list_type()> r1 = double_;
113
114 ut.clear();
115 BOOST_TEST(test_attr("1.2ab", r1 >> *char_, ut) &&
116 ut.which() == utree_type::list_type && check(ut, "( ( 1.2 ) \"a\" \"b\" )"));
117 ut.clear();
118 BOOST_TEST(test_attr("ab1.2", *~digit >> r1, ut) &&
119 ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" ( 1.2 ) )"));
120 ut.clear();
121
122 // implicitly a utree list, because of sequence attribute rules
123 rule<char const*, utree()> r2 = int_ >> char_("!") >> double_;
124
125 BOOST_TEST(test_attr("17!3.14", r2, ut) &&
126 ut.which() == utree_type::list_type && check(ut, "( 17 \"!\" 3.14 )"));
127 ut.clear();
128
129 rule<char const*, utree()> r3 = double_ >> as_string[string("foo")] >> int_;
130
131 BOOST_TEST(test_attr("0.5foo5", r3, ut) &&
132 ut.which() == utree_type::list_type && check(ut, "( 0.5 \"foo\" 5 )"));
133 }
134
135 {
136 utree ut;
137
138 rule<char const*, utree()> r1 = char_;
139 rule<char const*, utree::list_type()> r2 = double_;
140 rule<char const*, utree::list_type()> r3 = char_;
141
142 BOOST_TEST(test_attr("a25.5b", r1 >> r2 >> r3, ut));
143 BOOST_TEST(ut.which() == utree_type::list_type);
144 BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )"));
145 ut.clear();
146
147 BOOST_TEST(test_attr("a25.5b", r3 >> r2 >> r1, ut));
148 BOOST_TEST(ut.which() == utree_type::list_type);
149 BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )"));
150 ut.clear();
151
152 BOOST_TEST(test_attr("a25.5b", char_ >> r2 >> r3, ut));
153 BOOST_TEST(ut.which() == utree_type::list_type);
154 BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )"));
155 ut.clear();
156
157 BOOST_TEST(test_attr("a25.5b", r3 >> r2 >> char_, ut));
158 BOOST_TEST(ut.which() == utree_type::list_type);
159 BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )"));
160 ut.clear();
161
162#if defined(BOOST_CLANG)
163#pragma clang diagnostic push
164#pragma clang diagnostic ignored "-Woverloaded-shift-op-parentheses"
165#endif
166
167 BOOST_TEST(test_attr("a25.5b", r1 > r2 >> r3, ut));
168 BOOST_TEST(ut.which() == utree_type::list_type);
169 BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )"));
170 ut.clear();
171
172 BOOST_TEST(test_attr("a25.5b", r3 >> r2 > r1, ut));
173 BOOST_TEST(ut.which() == utree_type::list_type);
174 BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )"));
175 ut.clear();
176
177 BOOST_TEST(test_attr("a25.5b", char_ > r2 >> r3, ut));
178 BOOST_TEST(ut.which() == utree_type::list_type);
179 BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )"));
180 ut.clear();
181
182 BOOST_TEST(test_attr("a25.5b", r3 >> r2 > char_, ut));
183 BOOST_TEST(ut.which() == utree_type::list_type);
184 BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )"));
185
186#if defined(BOOST_CLANG)
187#pragma clang diagnostic pop
188#endif
189 }
190
191 return boost::report_errors();
192}
193
194

source code of boost/libs/spirit/test/qi/utree1.cpp