utree4.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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/mpl/print.hpp>
  12. #include <sstream>
  13. #include "test.hpp"
  14. inline bool check(boost::spirit::utree const& val, std::string expected)
  15. {
  16. std::stringstream s;
  17. s << val;
  18. if (s.str() == expected + " ")
  19. return true;
  20. std::cerr << "got result: " << s.str()
  21. << ", expected: " << expected << std::endl;
  22. return false;
  23. }
  24. int main()
  25. {
  26. using spirit_test::test_attr;
  27. using boost::spirit::utree;
  28. using boost::spirit::utree_type;
  29. using boost::spirit::utf8_string_range_type;
  30. using boost::spirit::utf8_symbol_type;
  31. using boost::spirit::utf8_string_type;
  32. using boost::spirit::qi::real_parser;
  33. using boost::spirit::qi::strict_real_policies;
  34. using boost::spirit::qi::digit;
  35. using boost::spirit::qi::char_;
  36. using boost::spirit::qi::string;
  37. using boost::spirit::qi::int_;
  38. using boost::spirit::qi::double_;
  39. using boost::spirit::qi::space;
  40. using boost::spirit::qi::space_type;
  41. using boost::spirit::qi::rule;
  42. using boost::spirit::qi::as;
  43. using boost::spirit::qi::lexeme;
  44. // as
  45. {
  46. typedef as<std::string> as_string_type;
  47. as_string_type const as_string = as_string_type();
  48. typedef as<utf8_symbol_type> as_symbol_type;
  49. as_symbol_type const as_symbol = as_symbol_type();
  50. utree ut;
  51. BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) &&
  52. ut.which() == utree_type::string_type && check(ut, "\"xy\""));
  53. ut.clear();
  54. BOOST_TEST(test_attr("ab1.2", as_string[*~digit] >> double_, ut) &&
  55. ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
  56. ut.clear();
  57. BOOST_TEST(test_attr("xy", as_string[*char_], ut) &&
  58. ut.which() == utree_type::string_type && check(ut, "\"xy\""));
  59. ut.clear();
  60. BOOST_TEST(test_attr("x,y", as_string[char_ >> ',' >> char_], ut) &&
  61. ut.which() == utree_type::string_type && check(ut, "\"xy\""));
  62. ut.clear();
  63. BOOST_TEST(test_attr("x,y", char_ >> ',' >> char_, ut) &&
  64. ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )"));
  65. ut.clear();
  66. BOOST_TEST(test_attr("a,b1.2", as_string[~digit % ','] >> double_, ut) &&
  67. ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
  68. ut.clear();
  69. BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) &&
  70. ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
  71. ut.clear();
  72. BOOST_TEST(test_attr("xy", as_symbol[char_ >> char_], ut) &&
  73. ut.which() == utree_type::symbol_type && check(ut, "xy"));
  74. ut.clear();
  75. BOOST_TEST(test_attr("ab1.2", as_symbol[*~digit] >> double_, ut) &&
  76. ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
  77. ut.clear();
  78. BOOST_TEST(test_attr("xy", as_symbol[*char_], ut) &&
  79. ut.which() == utree_type::symbol_type && check(ut, "xy"));
  80. ut.clear();
  81. BOOST_TEST(test_attr("x,y", as_symbol[char_ >> ',' >> char_], ut) &&
  82. ut.which() == utree_type::symbol_type && check(ut, "xy"));
  83. ut.clear();
  84. BOOST_TEST(test_attr("a,b1.2", as_symbol[~digit % ','] >> double_, ut) &&
  85. ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
  86. ut.clear();
  87. }
  88. // subtrees
  89. {
  90. // -(+int_) is forcing a subtree
  91. utree ut;
  92. BOOST_TEST(test_attr("1 2", int_ >> ' ' >> -(+int_), ut) &&
  93. ut.which() == utree_type::list_type && check(ut, "( 1 2 )"));
  94. ut.clear();
  95. BOOST_TEST(test_attr("1 2", int_ >> ' ' >> *int_, ut) &&
  96. ut.which() == utree_type::list_type && check(ut, "( 1 2 )"));
  97. ut.clear();
  98. rule<char const*, std::vector<int>()> r1 = int_ % ',';
  99. BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r1, ut) &&
  100. ut.which() == utree_type::list_type && check(ut, "( 1 2 3 )"));
  101. ut.clear();
  102. BOOST_TEST(test_attr("1,2 2,3", r1 >> ' ' >> r1, ut) &&
  103. ut.which() == utree_type::list_type && check(ut, "( 1 2 2 3 )"));
  104. ut.clear();
  105. rule<char const*, utree()> r2 = int_ % ',';
  106. BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r2, ut) &&
  107. ut.which() == utree_type::list_type && check(ut, "( 1 2 3 )"));
  108. ut.clear();
  109. BOOST_TEST(test_attr("1,2 2,3", r2 >> ' ' >> r2, ut) &&
  110. ut.which() == utree_type::list_type && check(ut, "( 1 2 2 3 )"));
  111. ut.clear();
  112. rule<char const*, utree::list_type()> r3 = int_ % ',';
  113. BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r3, ut) &&
  114. ut.which() == utree_type::list_type && check(ut, "( 1 ( 2 3 ) )"));
  115. ut.clear();
  116. BOOST_TEST(test_attr("1,2 2,3", r3 >> ' ' >> r3, ut) &&
  117. ut.which() == utree_type::list_type && check(ut, "( ( 1 2 ) ( 2 3 ) )"));
  118. ut.clear();
  119. rule<char const*, utree()> r4 = int_;
  120. BOOST_TEST(test_attr("1 1", int_ >> ' ' >> -r4, ut) &&
  121. ut.which() == utree_type::list_type && check(ut, "( 1 1 )"));
  122. ut.clear();
  123. BOOST_TEST(test_attr("1 ", int_ >> ' ' >> -r4, ut) &&
  124. ut.which() == utree_type::list_type && check(ut, "( 1 )"));
  125. ut.clear();
  126. rule<char const*, utree::list_type()> r5 = -r4;
  127. BOOST_TEST(test_attr("1", r5, ut) &&
  128. ut.which() == utree_type::list_type && check(ut, "( 1 )"));
  129. ut.clear();
  130. BOOST_TEST(test_attr("", r5, ut) &&
  131. ut.which() == utree_type::list_type && check(ut, "( )"));
  132. ut.clear();
  133. BOOST_TEST(test_attr("1 1", r5 >> ' ' >> r5, ut) &&
  134. ut.which() == utree_type::list_type && check(ut, "( ( 1 ) ( 1 ) )"));
  135. ut.clear();
  136. rule<char const*, utree::list_type()> r6 = int_;
  137. rule<char const*, utree()> r7 = -r6;
  138. BOOST_TEST(test_attr("1", r7, ut) &&
  139. ut.which() == utree_type::list_type && check(ut, "( 1 )"));
  140. ut.clear();
  141. rule<char const*, utree::list_type()> r8 = r6 >> ' ' >> r6;
  142. BOOST_TEST(test_attr("1 1", r8, ut) &&
  143. ut.which() == utree_type::list_type && check(ut, "( ( 1 ) ( 1 ) )"));
  144. ut.clear();
  145. }
  146. return boost::report_errors();
  147. }