kleene.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. #ifndef BOOST_SPIRIT_QI_OPERATOR_KLEENE_HPP
  8. #define BOOST_SPIRIT_QI_OPERATOR_KLEENE_HPP
  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 <boost/proto/operators.hpp>
  22. #include <boost/proto/tags.hpp>
  23. namespace boost { namespace spirit
  24. {
  25. ///////////////////////////////////////////////////////////////////////////
  26. // Enablers
  27. ///////////////////////////////////////////////////////////////////////////
  28. //[composite_parsers_kleene_enable_
  29. template <>
  30. struct use_operator<qi::domain, proto::tag::dereference> // enables *p
  31. : mpl::true_ {};
  32. //]
  33. }}
  34. namespace boost { namespace spirit { namespace qi
  35. {
  36. //[composite_parsers_kleene
  37. template <typename Subject>
  38. struct kleene : unary_parser<kleene<Subject> >
  39. {
  40. typedef Subject subject_type;
  41. template <typename Context, typename Iterator>
  42. struct attribute
  43. {
  44. // Build a std::vector from the subject's attribute. Note
  45. // that build_std_vector may return unused_type if the
  46. // subject's attribute is an unused_type.
  47. typedef typename
  48. traits::build_std_vector<
  49. typename traits::
  50. attribute_of<Subject, Context, Iterator>::type
  51. >::type
  52. type;
  53. };
  54. kleene(Subject const& subject_)
  55. : subject(subject_) {}
  56. template <typename F>
  57. bool parse_container(F f) const
  58. {
  59. while (!f (subject))
  60. ;
  61. return true;
  62. }
  63. template <typename Iterator, typename Context
  64. , typename Skipper, typename Attribute>
  65. bool parse(Iterator& first, Iterator const& last
  66. , Context& context, Skipper const& skipper
  67. , Attribute& attr_) const
  68. {
  69. // ensure the attribute is actually a container type
  70. traits::make_container(attr_);
  71. typedef detail::fail_function<Iterator, Context, Skipper>
  72. fail_function;
  73. Iterator iter = first;
  74. fail_function f(iter, last, context, skipper);
  75. parse_container(detail::make_pass_container(f, attr_));
  76. first = f.first;
  77. return true;
  78. }
  79. template <typename Context>
  80. info what(Context& context) const
  81. {
  82. return info("kleene", subject.what(context));
  83. }
  84. Subject subject;
  85. };
  86. //]
  87. ///////////////////////////////////////////////////////////////////////////
  88. // Parser generators: make_xxx function (objects)
  89. ///////////////////////////////////////////////////////////////////////////
  90. //[composite_parsers_kleene_generator
  91. template <typename Elements, typename Modifiers>
  92. struct make_composite<proto::tag::dereference, Elements, Modifiers>
  93. : make_unary_composite<Elements, kleene>
  94. {};
  95. //]
  96. // ///////////////////////////////////////////////////////////////////////////
  97. // // Define what attributes are compatible with a kleene
  98. // template <typename Attribute, typename Subject, typename Context, typename Iterator>
  99. // struct is_attribute_compatible<Attribute, kleene<Subject>, Context, Iterator>
  100. // : traits::is_container_compatible<qi::domain, Attribute
  101. // , kleene<Subject>, Context, Iterator>
  102. // {};
  103. }}}
  104. namespace boost { namespace spirit { namespace traits
  105. {
  106. ///////////////////////////////////////////////////////////////////////////
  107. template <typename Subject>
  108. struct has_semantic_action<qi::kleene<Subject> >
  109. : unary_has_semantic_action<Subject> {};
  110. ///////////////////////////////////////////////////////////////////////////
  111. template <typename Subject, typename Attribute, typename Context
  112. , typename Iterator>
  113. struct handles_container<qi::kleene<Subject>, Attribute
  114. , Context, Iterator>
  115. : mpl::true_ {};
  116. }}}
  117. #endif