1 // Copyright (c) 2001-2011 Hartmut Kaiser
2 // Copyright (c) 2001-2011 Joel de Guzman
3 // Copyright (c) 2010 Bryce Lelbach
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)
8 #include <boost/spirit/include/qi.hpp>
9 #include <boost/spirit/include/support_utree.hpp>
10 #include <boost/type_traits/is_same.hpp>
16 template <typename Expr
, typename Iterator
= boost::spirit::unused_type
>
17 struct attribute_of_parser
19 typedef typename
boost::spirit::result_of::compile
<
20 boost::spirit::qi::domain
, Expr
21 >::type parser_expression_type
;
23 typedef typename
boost::spirit::traits::attribute_of
<
24 parser_expression_type
, boost::spirit::unused_type
, Iterator
28 template <typename Expected
, typename Expr
>
29 inline bool compare_attribute_type(Expr
const&)
31 typedef typename attribute_of_parser
<Expr
>::type type
;
32 return boost::is_same
<type
, Expected
>::value
;
35 inline bool check(boost::spirit::utree
const& val
, std::string expected
)
39 if (s
.str() == expected
+ " ")
42 std::cerr
<< "got result: " << s
.str()
43 << ", expected: " << expected
<< std::endl
;
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
;
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
;
71 typedef real_parser
<double, strict_real_policies
<double> >
73 strict_double_type
const strict_double
= strict_double_type();
76 BOOST_TEST(test_attr("xy", *char_
, ut
) &&
77 ut
.which() == utree_type::list_type
&& check(ut
, "( \"x\" \"y\" )"));
79 BOOST_TEST(test_attr("123 456", *int_
, ut
, space
) &&
80 ut
.which() == utree_type::list_type
&& check(ut
, "( 123 456 )"));
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 )"));
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
;
90 BOOST_TEST(test_attr("(x y)", r1
, ut
, space
) &&
91 ut
.which() == utree_type::list_type
&& check(ut
, "( \"x\" \"y\" )"));
93 BOOST_TEST(test_attr("(((123)) 456)", r1
, ut
, space
) &&
94 ut
.which() == utree_type::list_type
&& check(ut
, "( ( ( 123 ) ) 456 )"));
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 ) )"));
99 BOOST_TEST(test_attr("x", r1
, ut
, space
) &&
100 ut
.which() == utree_type::string_type
&& check(ut
, "\"x\""));
102 BOOST_TEST(test_attr("123", r1
, ut
, space
) &&
103 ut
.which() == utree_type::int_type
&& check(ut
, "123"));
105 BOOST_TEST(test_attr("123.456", r1
, ut
, space
) &&
106 ut
.which() == utree_type::double_type
&& check(ut
, "123.456"));
108 BOOST_TEST(test_attr("()", r1
, ut
, space
) &&
109 ut
.which() == utree_type::list_type
&&
112 BOOST_TEST(test_attr("((()))", r1
, ut
, space
) &&
113 ut
.which() == utree_type::list_type
&&
114 check(ut
, "( ( ( ) ) )"));
118 // special attribute transformation for utree in alternatives
120 rule
<char const*, utree()> r1
;
121 rule
<char const*, utree::list_type()> r2
;
123 BOOST_TEST(compare_attribute_type
<utree
>(
124 r1
| -r1
| *r1
| r2
| -r2
| *r2
));
130 BOOST_TEST(test_attr("x,y", char_
% ',', ut
) &&
131 ut
.which() == utree_type::list_type
&& check(ut
, "( \"x\" \"y\" )"));
133 BOOST_TEST(test_attr("123,456", int_
% ',', ut
) &&
134 ut
.which() == utree_type::list_type
&& check(ut
, "( 123 456 )"));
136 BOOST_TEST(test_attr("1.23,4.56", double_
% ',', ut
) &&
137 ut
.which() == utree_type::list_type
&& check(ut
, "( 1.23 4.56 )"));
139 rule
<char const*, std::vector
<char>()> r1
= char_
% ',';
141 BOOST_TEST(test_attr("x,y", r1
, ut
) &&
142 ut
.which() == utree_type::list_type
&& check(ut
, "( \"x\" \"y\" )"));
144 rule
<char const*, std::vector
<int>()> r2
= int_
% ',';
146 BOOST_TEST(test_attr("123,456", r2
, ut
) &&
147 ut
.which() == utree_type::list_type
&& check(ut
, "( 123 456 )"));
149 rule
<char const*, std::vector
<double>()> r3
= double_
% ',';
151 BOOST_TEST(test_attr("1.23,4.56", r3
, ut
) &&
152 ut
.which() == utree_type::list_type
&& check(ut
, "( 1.23 4.56 )"));
154 rule
<char const*, utree()> r4
= double_
% ',';
156 BOOST_TEST(test_attr("1.23,4.56", r4
, ut
) &&
157 ut
.which() == utree_type::list_type
&& check(ut
, "( 1.23 4.56 )"));
160 return boost::report_errors();