list.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
  8. #define SPIRIT_LIST_MARCH_24_2007_1031AM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/spirit/home/qi/meta_compiler.hpp>
  13. #include <boost/spirit/home/qi/parser.hpp>
  14. #include <boost/spirit/home/support/container.hpp>
  15. #include <boost/spirit/home/qi/detail/attributes.hpp>
  16. #include <boost/spirit/home/qi/detail/fail_function.hpp>
  17. #include <boost/spirit/home/qi/detail/pass_container.hpp>
  18. #include <boost/spirit/home/support/has_semantic_action.hpp>
  19. #include <boost/spirit/home/support/handles_container.hpp>
  20. #include <boost/spirit/home/support/info.hpp>
  21. #include <vector>
  22. namespace boost { namespace spirit
  23. {
  24. ///////////////////////////////////////////////////////////////////////////
  25. // Enablers
  26. ///////////////////////////////////////////////////////////////////////////
  27. template <>
  28. struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
  29. : mpl::true_ {};
  30. }}
  31. namespace boost { namespace spirit { namespace qi
  32. {
  33. template <typename Left, typename Right>
  34. struct list : binary_parser<list<Left, Right> >
  35. {
  36. typedef Left left_type;
  37. typedef Right right_type;
  38. template <typename Context, typename Iterator>
  39. struct attribute
  40. {
  41. // Build a std::vector from the LHS's attribute. Note
  42. // that build_std_vector may return unused_type if the
  43. // subject's attribute is an unused_type.
  44. typedef typename
  45. traits::build_std_vector<
  46. typename traits::
  47. attribute_of<Left, Context, Iterator>::type
  48. >::type
  49. type;
  50. };
  51. list(Left const& left_, Right const& right_)
  52. : left(left_), right(right_) {}
  53. template <typename F>
  54. bool parse_container(F f) const
  55. {
  56. // in order to succeed we need to match at least one element
  57. if (f (left))
  58. return false;
  59. typename F::iterator_type save = f.f.first;
  60. while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
  61. && !f (left))
  62. {
  63. save = f.f.first;
  64. }
  65. f.f.first = save;
  66. return true;
  67. }
  68. template <typename Iterator, typename Context
  69. , typename Skipper, typename Attribute>
  70. bool parse(Iterator& first, Iterator const& last
  71. , Context& context, Skipper const& skipper
  72. , Attribute& attr_) const
  73. {
  74. typedef detail::fail_function<Iterator, Context, Skipper>
  75. fail_function;
  76. // ensure the attribute is actually a container type
  77. traits::make_container(attr_);
  78. Iterator iter = first;
  79. fail_function f(iter, last, context, skipper);
  80. if (!parse_container(detail::make_pass_container(f, attr_)))
  81. return false;
  82. first = f.first;
  83. return true;
  84. }
  85. template <typename Context>
  86. info what(Context& context) const
  87. {
  88. return info("list",
  89. std::make_pair(left.what(context), right.what(context)));
  90. }
  91. Left left;
  92. Right right;
  93. };
  94. ///////////////////////////////////////////////////////////////////////////
  95. // Parser generators: make_xxx function (objects)
  96. ///////////////////////////////////////////////////////////////////////////
  97. template <typename Elements, typename Modifiers>
  98. struct make_composite<proto::tag::modulus, Elements, Modifiers>
  99. : make_binary_composite<Elements, list>
  100. {};
  101. }}}
  102. namespace boost { namespace spirit { namespace traits
  103. {
  104. ///////////////////////////////////////////////////////////////////////////
  105. template <typename Left, typename Right>
  106. struct has_semantic_action<qi::list<Left, Right> >
  107. : binary_has_semantic_action<Left, Right> {};
  108. ///////////////////////////////////////////////////////////////////////////
  109. template <typename Left, typename Right, typename Attribute
  110. , typename Context, typename Iterator>
  111. struct handles_container<qi::list<Left, Right>, Attribute, Context
  112. , Iterator>
  113. : mpl::true_ {};
  114. }}}
  115. #endif