epsilon.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*=============================================================================
  2. Copyright (c) 1998-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_EPSILON_HPP
  9. #define BOOST_SPIRIT_EPSILON_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/meta/parser_traits.hpp>
  14. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  15. #include <boost/spirit/home/classic/core/composite/no_actions.hpp>
  16. #if defined(BOOST_MSVC)
  17. # pragma warning(push)
  18. # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
  19. #endif
  20. ////////////////////////////////////////////////////////////////////////////////
  21. namespace boost { namespace spirit {
  22. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  23. ///////////////////////////////////////////////////////////////////////////////
  24. //
  25. // condition_parser class
  26. //
  27. // handles expresions of the form
  28. //
  29. // epsilon_p(cond)
  30. //
  31. // where cond is a function or a functor that returns a value suitable
  32. // to be used in boolean context. The expression returns a parser that
  33. // returns an empty match when the condition evaluates to true.
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. template <typename CondT, bool positive_ = true>
  37. struct condition_parser : parser<condition_parser<CondT, positive_> >
  38. {
  39. typedef condition_parser<CondT, positive_> self_t;
  40. // not explicit! (needed for implementation of if_p et al.)
  41. condition_parser(CondT const& cond_) : cond(cond_) {}
  42. template <typename ScannerT>
  43. typename parser_result<self_t, ScannerT>::type
  44. parse(ScannerT const& scan) const
  45. {
  46. if (positive_ == bool(cond())) // allow cond to return int
  47. return scan.empty_match();
  48. else
  49. return scan.no_match();
  50. }
  51. condition_parser<CondT, !positive_>
  52. negate() const
  53. { return condition_parser<CondT, !positive_>(cond); }
  54. private:
  55. CondT cond;
  56. };
  57. #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
  58. BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \
  59. BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
  60. // VC 7.1, VC8 and Sun CC <= 5.8 do not support general
  61. // expressions of non-type template parameters in instantiations
  62. template <typename CondT>
  63. inline condition_parser<CondT, false>
  64. operator~(condition_parser<CondT, true> const& p)
  65. { return p.negate(); }
  66. template <typename CondT>
  67. inline condition_parser<CondT, true>
  68. operator~(condition_parser<CondT, false> const& p)
  69. { return p.negate(); }
  70. #else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
  71. template <typename CondT, bool positive>
  72. inline condition_parser<CondT, !positive>
  73. operator~(condition_parser<CondT, positive> const& p)
  74. { return p.negate(); }
  75. #endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
  76. ///////////////////////////////////////////////////////////////////////////////
  77. //
  78. // empty_match_parser class
  79. //
  80. // handles expressions of the form
  81. // epsilon_p(subject)
  82. // where subject is a parser. The expresion returns a composite
  83. // parser that returns an empty match if the subject parser matches.
  84. //
  85. ///////////////////////////////////////////////////////////////////////////////
  86. struct empty_match_parser_gen;
  87. struct negated_empty_match_parser_gen;
  88. template <typename SubjectT>
  89. struct negated_empty_match_parser; // Forward declaration
  90. template<typename SubjectT>
  91. struct empty_match_parser
  92. : unary<SubjectT, parser<empty_match_parser<SubjectT> > >
  93. {
  94. typedef empty_match_parser<SubjectT> self_t;
  95. typedef unary<SubjectT, parser<self_t> > base_t;
  96. typedef unary_parser_category parser_category_t;
  97. typedef empty_match_parser_gen parser_genererator_t;
  98. typedef self_t embed_t;
  99. explicit empty_match_parser(SubjectT const& p) : base_t(p) {}
  100. template <typename ScannerT>
  101. struct result
  102. { typedef typename match_result<ScannerT, nil_t>::type type; };
  103. template <typename ScannerT>
  104. typename parser_result<self_t, ScannerT>::type
  105. parse(ScannerT const& scan) const
  106. {
  107. typename ScannerT::iterator_t save(scan.first);
  108. typedef typename no_actions_scanner<ScannerT>::policies_t
  109. policies_t;
  110. bool matches = this->subject().parse(
  111. scan.change_policies(policies_t(scan)));
  112. if (matches)
  113. {
  114. scan.first = save; // reset the position
  115. return scan.empty_match();
  116. }
  117. else
  118. {
  119. return scan.no_match();
  120. }
  121. }
  122. negated_empty_match_parser<SubjectT>
  123. negate() const
  124. { return negated_empty_match_parser<SubjectT>(this->subject()); }
  125. };
  126. template<typename SubjectT>
  127. struct negated_empty_match_parser
  128. : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
  129. {
  130. typedef negated_empty_match_parser<SubjectT> self_t;
  131. typedef unary<SubjectT, parser<self_t> > base_t;
  132. typedef unary_parser_category parser_category_t;
  133. typedef negated_empty_match_parser_gen parser_genererator_t;
  134. explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {}
  135. template <typename ScannerT>
  136. struct result
  137. { typedef typename match_result<ScannerT, nil_t>::type type; };
  138. template <typename ScannerT>
  139. typename parser_result<self_t, ScannerT>::type
  140. parse(ScannerT const& scan) const
  141. {
  142. typename ScannerT::iterator_t save(scan.first);
  143. typedef typename no_actions_scanner<ScannerT>::policies_t
  144. policies_t;
  145. bool matches = this->subject().parse(
  146. scan.change_policies(policies_t(scan)));
  147. if (!matches)
  148. {
  149. scan.first = save; // reset the position
  150. return scan.empty_match();
  151. }
  152. else
  153. {
  154. return scan.no_match();
  155. }
  156. }
  157. empty_match_parser<SubjectT>
  158. negate() const
  159. { return empty_match_parser<SubjectT>(this->subject()); }
  160. };
  161. struct empty_match_parser_gen
  162. {
  163. template <typename SubjectT>
  164. struct result
  165. { typedef empty_match_parser<SubjectT> type; };
  166. template <typename SubjectT>
  167. static empty_match_parser<SubjectT>
  168. generate(parser<SubjectT> const& subject)
  169. { return empty_match_parser<SubjectT>(subject.derived()); }
  170. };
  171. struct negated_empty_match_parser_gen
  172. {
  173. template <typename SubjectT>
  174. struct result
  175. { typedef negated_empty_match_parser<SubjectT> type; };
  176. template <typename SubjectT>
  177. static negated_empty_match_parser<SubjectT>
  178. generate(parser<SubjectT> const& subject)
  179. { return negated_empty_match_parser<SubjectT>(subject.derived()); }
  180. };
  181. //////////////////////////////
  182. template <typename SubjectT>
  183. inline negated_empty_match_parser<SubjectT>
  184. operator~(empty_match_parser<SubjectT> const& p)
  185. { return p.negate(); }
  186. template <typename SubjectT>
  187. inline empty_match_parser<SubjectT>
  188. operator~(negated_empty_match_parser<SubjectT> const& p)
  189. { return p.negate(); }
  190. ///////////////////////////////////////////////////////////////////////////////
  191. //
  192. // epsilon_ parser and parser generator class
  193. //
  194. // Operates as primitive parser that always matches an empty sequence.
  195. //
  196. // Also operates as a parser generator. According to the type of the
  197. // argument an instance of empty_match_parser<> (when the argument is
  198. // a parser) or condition_parser<> (when the argument is not a parser)
  199. // is returned by operator().
  200. //
  201. ///////////////////////////////////////////////////////////////////////////////
  202. namespace impl
  203. {
  204. template <typename SubjectT>
  205. struct epsilon_selector
  206. {
  207. typedef typename as_parser<SubjectT>::type subject_t;
  208. typedef typename
  209. mpl::if_<
  210. is_parser<subject_t>
  211. ,empty_match_parser<subject_t>
  212. ,condition_parser<subject_t>
  213. >::type type;
  214. };
  215. }
  216. struct epsilon_parser : public parser<epsilon_parser>
  217. {
  218. typedef epsilon_parser self_t;
  219. epsilon_parser() {}
  220. template <typename ScannerT>
  221. typename parser_result<self_t, ScannerT>::type
  222. parse(ScannerT const& scan) const
  223. { return scan.empty_match(); }
  224. template <typename SubjectT>
  225. typename impl::epsilon_selector<SubjectT>::type
  226. operator()(SubjectT const& subject) const
  227. {
  228. typedef typename impl::epsilon_selector<SubjectT>::type result_t;
  229. return result_t(subject);
  230. }
  231. };
  232. epsilon_parser const epsilon_p = epsilon_parser();
  233. epsilon_parser const eps_p = epsilon_parser();
  234. ///////////////////////////////////////////////////////////////////////////////
  235. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  236. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  237. #ifdef BOOST_MSVC
  238. # pragma warning (pop)
  239. #endif
  240. #endif