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 | #include <boost/type_traits/is_same.hpp> |
11 | |
12 | #include <sstream> |
13 | |
14 | #include "test.hpp" |
15 | |
16 | template <typename Expr, typename Iterator = boost::spirit::unused_type> |
17 | struct attribute_of_parser |
18 | { |
19 | typedef typename boost::spirit::result_of::compile< |
20 | boost::spirit::qi::domain, Expr |
21 | >::type parser_expression_type; |
22 | |
23 | typedef typename boost::spirit::traits::attribute_of< |
24 | parser_expression_type, boost::spirit::unused_type, Iterator |
25 | >::type type; |
26 | }; |
27 | |
28 | template <typename Expected, typename Expr> |
29 | inline bool compare_attribute_type(Expr const&) |
30 | { |
31 | typedef typename attribute_of_parser<Expr>::type type; |
32 | return boost::is_same<type, Expected>::value; |
33 | } |
34 | |
35 | inline bool check(boost::spirit::utree const& val, std::string expected) |
36 | { |
37 | std::stringstream s; |
38 | s << val; |
39 | if (s.str() == expected + " " ) |
40 | return true; |
41 | |
42 | std::cerr << "got result: " << s.str() |
43 | << ", expected: " << expected << std::endl; |
44 | return false; |
45 | } |
46 | |
47 | int main() |
48 | { |
49 | using spirit_test::test_attr; |
50 | using boost::spirit::utree; |
51 | using boost::spirit::utree_type; |
52 | using boost::spirit::utf8_string_range_type; |
53 | using boost::spirit::utf8_symbol_type; |
54 | using boost::spirit::utf8_string_type; |
55 | |
56 | using boost::spirit::qi::real_parser; |
57 | using boost::spirit::qi::strict_real_policies; |
58 | using boost::spirit::qi::digit; |
59 | using boost::spirit::qi::char_; |
60 | using boost::spirit::qi::string; |
61 | using boost::spirit::qi::int_; |
62 | using boost::spirit::qi::double_; |
63 | using boost::spirit::qi::space; |
64 | using boost::spirit::qi::space_type; |
65 | using boost::spirit::qi::rule; |
66 | using boost::spirit::qi::as; |
67 | using boost::spirit::qi::lexeme; |
68 | |
69 | // kleene star |
70 | { |
71 | typedef real_parser<double, strict_real_policies<double> > |
72 | strict_double_type; |
73 | strict_double_type const strict_double = strict_double_type(); |
74 | |
75 | utree ut; |
76 | BOOST_TEST(test_attr("xy" , *char_, ut) && |
77 | ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )" )); |
78 | ut.clear(); |
79 | BOOST_TEST(test_attr("123 456" , *int_, ut, space) && |
80 | ut.which() == utree_type::list_type && check(ut, "( 123 456 )" )); |
81 | ut.clear(); |
82 | BOOST_TEST(test_attr("1.23 4.56" , *double_, ut, space) && |
83 | ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )" )); |
84 | ut.clear(); |
85 | |
86 | rule<char const*, utree(), space_type> r1; |
87 | rule<char const*, utree::list_type(), space_type> r2 = '(' >> *r1 >> ')'; |
88 | r1 = strict_double | int_ | ~char_("()" ) | r2; |
89 | |
90 | BOOST_TEST(test_attr("(x y)" , r1, ut, space) && |
91 | ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )" )); |
92 | ut.clear(); |
93 | BOOST_TEST(test_attr("(((123)) 456)" , r1, ut, space) && |
94 | ut.which() == utree_type::list_type && check(ut, "( ( ( 123 ) ) 456 )" )); |
95 | ut.clear(); |
96 | BOOST_TEST(test_attr("((1.23 4.56))" , r1, ut, space) && |
97 | ut.which() == utree_type::list_type && check(ut, "( ( 1.23 4.56 ) )" )); |
98 | ut.clear(); |
99 | BOOST_TEST(test_attr("x" , r1, ut, space) && |
100 | ut.which() == utree_type::string_type && check(ut, "\"x\"" )); |
101 | ut.clear(); |
102 | BOOST_TEST(test_attr("123" , r1, ut, space) && |
103 | ut.which() == utree_type::int_type && check(ut, "123" )); |
104 | ut.clear(); |
105 | BOOST_TEST(test_attr("123.456" , r1, ut, space) && |
106 | ut.which() == utree_type::double_type && check(ut, "123.456" )); |
107 | ut.clear(); |
108 | BOOST_TEST(test_attr("()" , r1, ut, space) && |
109 | ut.which() == utree_type::list_type && |
110 | check(ut, "( )" )); |
111 | ut.clear(); |
112 | BOOST_TEST(test_attr("((()))" , r1, ut, space) && |
113 | ut.which() == utree_type::list_type && |
114 | check(ut, "( ( ( ) ) )" )); |
115 | ut.clear(); |
116 | } |
117 | |
118 | // special attribute transformation for utree in alternatives |
119 | { |
120 | rule<char const*, utree()> r1; |
121 | rule<char const*, utree::list_type()> r2; |
122 | |
123 | BOOST_TEST(compare_attribute_type<utree>( |
124 | r1 | -r1 | *r1 | r2 | -r2 | *r2)); |
125 | } |
126 | |
127 | // lists |
128 | { |
129 | utree ut; |
130 | BOOST_TEST(test_attr("x,y" , char_ % ',', ut) && |
131 | ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )" )); |
132 | ut.clear(); |
133 | BOOST_TEST(test_attr("123,456" , int_ % ',', ut) && |
134 | ut.which() == utree_type::list_type && check(ut, "( 123 456 )" )); |
135 | ut.clear(); |
136 | BOOST_TEST(test_attr("1.23,4.56" , double_ % ',', ut) && |
137 | ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )" )); |
138 | |
139 | rule<char const*, std::vector<char>()> r1 = char_ % ','; |
140 | ut.clear(); |
141 | BOOST_TEST(test_attr("x,y" , r1, ut) && |
142 | ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )" )); |
143 | |
144 | rule<char const*, std::vector<int>()> r2 = int_ % ','; |
145 | ut.clear(); |
146 | BOOST_TEST(test_attr("123,456" , r2, ut) && |
147 | ut.which() == utree_type::list_type && check(ut, "( 123 456 )" )); |
148 | |
149 | rule<char const*, std::vector<double>()> r3 = double_ % ','; |
150 | ut.clear(); |
151 | BOOST_TEST(test_attr("1.23,4.56" , r3, ut) && |
152 | ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )" )); |
153 | |
154 | rule<char const*, utree()> r4 = double_ % ','; |
155 | ut.clear(); |
156 | BOOST_TEST(test_attr("1.23,4.56" , r4, ut) && |
157 | ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )" )); |
158 | } |
159 | |
160 | return boost::report_errors(); |
161 | } |
162 | |