for.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Joel de Guzman
  3. Copyright (c) 2002-2003 Martin Wille
  4. http://spirit.sourceforge.net/
  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. =============================================================================*/
  8. #ifndef BOOST_SPIRIT_FOR_HPP
  9. #define BOOST_SPIRIT_FOR_HPP
  10. ////////////////////////////////////////////////////////////////////////////////
  11. #include <boost/spirit/home/classic/namespace.hpp>
  12. #include <boost/spirit/home/classic/core/parser.hpp>
  13. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  14. #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
  15. ////////////////////////////////////////////////////////////////////////////////
  16. namespace boost { namespace spirit {
  17. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  18. namespace impl
  19. {
  20. template <typename FuncT>
  21. struct for_functor
  22. {
  23. typedef typename boost::call_traits<FuncT>::param_type param_t;
  24. for_functor(param_t f) : func(f) {}
  25. for_functor() {}
  26. FuncT func;
  27. };
  28. template <typename InitF>
  29. struct for_init_functor : for_functor<InitF>
  30. {
  31. typedef for_functor<InitF> base_t;
  32. typedef typename base_t::param_t param_t;
  33. for_init_functor(param_t f) : base_t(f) {}
  34. for_init_functor() : base_t() {}
  35. void init() const { /*return*/ this->func(); }
  36. };
  37. template <typename StepF>
  38. struct for_step_functor : for_functor<StepF>
  39. {
  40. typedef for_functor<StepF> base_t;
  41. typedef typename base_t::param_t param_t;
  42. for_step_functor(param_t f) : base_t(f) {}
  43. for_step_functor() : base_t() {}
  44. void step() const { /*return*/ this->func(); }
  45. };
  46. //////////////////////////////////
  47. // for_parser
  48. template
  49. <
  50. typename InitF, typename CondT, typename StepF,
  51. typename ParsableT
  52. >
  53. struct for_parser
  54. : private for_init_functor<InitF>
  55. , private for_step_functor<StepF>
  56. , private condition_evaluator<typename as_parser<CondT>::type>
  57. , public unary
  58. <
  59. typename as_parser<ParsableT>::type,
  60. parser< for_parser<InitF, CondT, StepF, ParsableT> >
  61. >
  62. {
  63. typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
  64. typedef as_parser<CondT> cond_as_parser_t;
  65. typedef typename cond_as_parser_t::type condition_t;
  66. typedef condition_evaluator<condition_t> eval_t;
  67. typedef as_parser<ParsableT> as_parser_t;
  68. typedef typename as_parser_t::type parser_t;
  69. typedef unary< parser_t, parser< self_t > > base_t;
  70. //////////////////////////////
  71. // constructor, saves init, condition and step functors
  72. // for later use the parse member function
  73. for_parser
  74. (
  75. InitF const &i, CondT const &c, StepF const &s,
  76. ParsableT const &p
  77. )
  78. : for_init_functor<InitF>(i)
  79. , for_step_functor<StepF>(s)
  80. , eval_t(cond_as_parser_t::convert(c))
  81. , base_t(as_parser_t::convert(p))
  82. { }
  83. for_parser()
  84. : for_init_functor<InitF>()
  85. , for_step_functor<StepF>()
  86. , eval_t()
  87. , base_t()
  88. {}
  89. //////////////////////////////
  90. // parse member function
  91. template <typename ScannerT>
  92. typename parser_result<self_t, ScannerT>::type
  93. parse(ScannerT const &scan) const
  94. {
  95. typedef typename parser_result<parser_t, ScannerT>::type
  96. body_result_t;
  97. typename ScannerT::iterator_t save(scan.first);
  98. std::size_t length = 0;
  99. std::ptrdiff_t eval_length = 0;
  100. this->init();
  101. while ((eval_length = this->evaluate(scan))>=0)
  102. {
  103. length += eval_length;
  104. body_result_t tmp(this->subject().parse(scan));
  105. if (tmp)
  106. {
  107. length+=tmp.length();
  108. }
  109. else
  110. {
  111. return scan.no_match();
  112. }
  113. this->step();
  114. }
  115. BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
  116. return scan.create_match
  117. (length, attr, save, scan.first);
  118. }
  119. };
  120. //////////////////////////////////
  121. // for_parser_gen generates takes the body parser in brackets
  122. // and returns the for_parser
  123. template <typename InitF, typename CondT, typename StepF>
  124. struct for_parser_gen
  125. {
  126. for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
  127. : init(i)
  128. , condition(c)
  129. , step(s)
  130. {}
  131. template <typename ParsableT>
  132. for_parser<InitF, CondT, StepF, ParsableT>
  133. operator[](ParsableT const &p) const
  134. {
  135. return for_parser<InitF, CondT, StepF, ParsableT>
  136. (init, condition, step, p);
  137. }
  138. InitF const &init;
  139. CondT const &condition;
  140. StepF const &step;
  141. };
  142. } // namespace impl
  143. //////////////////////////////
  144. // for_p, returns for-parser generator
  145. // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
  146. template
  147. <
  148. typename InitF, typename ConditionT, typename StepF
  149. >
  150. impl::for_parser_gen<InitF, ConditionT, StepF>
  151. for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
  152. {
  153. return impl::for_parser_gen<InitF, ConditionT, StepF>
  154. (init_f, condition, step_f);
  155. }
  156. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  157. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  158. #endif // BOOST_SPIRIT_FOR_HPP