utree2.cpp 5.8 KB

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