confix.ipp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*=============================================================================
  2. Copyright (c) 2002-2003 Hartmut Kaiser
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #ifndef BOOST_SPIRIT_CONFIX_IPP
  9. #define BOOST_SPIRIT_CONFIX_IPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include <boost/spirit/home/classic/meta/refactoring.hpp>
  12. #include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
  13. ///////////////////////////////////////////////////////////////////////////////
  14. namespace boost { namespace spirit {
  15. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  16. ///////////////////////////////////////////////////////////////////////////////
  17. //
  18. // Types to distinguish nested and non-nested confix parsers
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. struct is_nested {};
  22. struct non_nested {};
  23. ///////////////////////////////////////////////////////////////////////////////
  24. //
  25. // Types to distinguish between confix parsers, which are implicitly lexems
  26. // and without this behaviour
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////
  29. struct is_lexeme {};
  30. struct non_lexeme {};
  31. ///////////////////////////////////////////////////////////////////////////////
  32. //
  33. // confix_parser_type class implementation
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. namespace impl {
  37. ///////////////////////////////////////////////////////////////////////////
  38. // implicitly insert a lexeme_d into the parsing process
  39. template <typename LexemeT>
  40. struct select_confix_parse_lexeme;
  41. template <>
  42. struct select_confix_parse_lexeme<is_lexeme> {
  43. template <typename ParserT, typename ScannerT>
  44. static typename parser_result<ParserT, ScannerT>::type
  45. parse(ParserT const& p, ScannerT const& scan)
  46. {
  47. typedef typename parser_result<ParserT, ScannerT>::type result_t;
  48. return contiguous_parser_parse<result_t>(p, scan, scan);
  49. }
  50. };
  51. template <>
  52. struct select_confix_parse_lexeme<non_lexeme> {
  53. template <typename ParserT, typename ScannerT>
  54. static typename parser_result<ParserT, ScannerT>::type
  55. parse(ParserT const& p, ScannerT const& scan)
  56. {
  57. return p.parse(scan);
  58. }
  59. };
  60. ///////////////////////////////////////////////////////////////////////////
  61. // parse confix sequences with refactoring
  62. template <typename NestedT>
  63. struct select_confix_parse_refactor;
  64. template <>
  65. struct select_confix_parse_refactor<is_nested> {
  66. template <
  67. typename LexemeT, typename ParserT, typename ScannerT,
  68. typename OpenT, typename ExprT, typename CloseT
  69. >
  70. static typename parser_result<ParserT, ScannerT>::type
  71. parse(
  72. LexemeT const &, ParserT const& this_, ScannerT const& scan,
  73. OpenT const& open, ExprT const& expr, CloseT const& close)
  74. {
  75. typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
  76. const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
  77. return select_confix_parse_lexeme<LexemeT>::parse((
  78. open
  79. >> (this_ | refactor_body_d[expr - close])
  80. >> close
  81. ), scan);
  82. }
  83. };
  84. template <>
  85. struct select_confix_parse_refactor<non_nested> {
  86. template <
  87. typename LexemeT, typename ParserT, typename ScannerT,
  88. typename OpenT, typename ExprT, typename CloseT
  89. >
  90. static typename parser_result<ParserT, ScannerT>::type
  91. parse(
  92. LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan,
  93. OpenT const& open, ExprT const& expr, CloseT const& close)
  94. {
  95. typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
  96. const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
  97. return select_confix_parse_lexeme<LexemeT>::parse((
  98. open
  99. >> refactor_body_d[expr - close]
  100. >> close
  101. ), scan);
  102. }
  103. };
  104. ///////////////////////////////////////////////////////////////////////////
  105. // parse confix sequences without refactoring
  106. template <typename NestedT>
  107. struct select_confix_parse_no_refactor;
  108. template <>
  109. struct select_confix_parse_no_refactor<is_nested> {
  110. template <
  111. typename LexemeT, typename ParserT, typename ScannerT,
  112. typename OpenT, typename ExprT, typename CloseT
  113. >
  114. static typename parser_result<ParserT, ScannerT>::type
  115. parse(
  116. LexemeT const &, ParserT const& this_, ScannerT const& scan,
  117. OpenT const& open, ExprT const& expr, CloseT const& close)
  118. {
  119. return select_confix_parse_lexeme<LexemeT>::parse((
  120. open
  121. >> (this_ | (expr - close))
  122. >> close
  123. ), scan);
  124. }
  125. };
  126. template <>
  127. struct select_confix_parse_no_refactor<non_nested> {
  128. template <
  129. typename LexemeT, typename ParserT, typename ScannerT,
  130. typename OpenT, typename ExprT, typename CloseT
  131. >
  132. static typename parser_result<ParserT, ScannerT>::type
  133. parse(
  134. LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan,
  135. OpenT const& open, ExprT const& expr, CloseT const& close)
  136. {
  137. return select_confix_parse_lexeme<LexemeT>::parse((
  138. open
  139. >> (expr - close)
  140. >> close
  141. ), scan);
  142. }
  143. };
  144. // the refactoring is handled by the refactoring parsers, so here there
  145. // is no need to pay attention to these issues.
  146. template <typename CategoryT>
  147. struct confix_parser_type {
  148. template <
  149. typename NestedT, typename LexemeT,
  150. typename ParserT, typename ScannerT,
  151. typename OpenT, typename ExprT, typename CloseT
  152. >
  153. static typename parser_result<ParserT, ScannerT>::type
  154. parse(
  155. NestedT const &, LexemeT const &lexeme,
  156. ParserT const& this_, ScannerT const& scan,
  157. OpenT const& open, ExprT const& expr, CloseT const& close)
  158. {
  159. return select_confix_parse_refactor<NestedT>::
  160. parse(lexeme, this_, scan, open, expr, close);
  161. }
  162. };
  163. template <>
  164. struct confix_parser_type<plain_parser_category> {
  165. template <
  166. typename NestedT, typename LexemeT,
  167. typename ParserT, typename ScannerT,
  168. typename OpenT, typename ExprT, typename CloseT
  169. >
  170. static typename parser_result<ParserT, ScannerT>::type
  171. parse(
  172. NestedT const &, LexemeT const &lexeme,
  173. ParserT const& this_, ScannerT const& scan,
  174. OpenT const& open, ExprT const& expr, CloseT const& close)
  175. {
  176. return select_confix_parse_no_refactor<NestedT>::
  177. parse(lexeme, this_, scan, open, expr, close);
  178. }
  179. };
  180. } // namespace impl
  181. ///////////////////////////////////////////////////////////////////////////////
  182. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  183. }} // namespace boost::spirit
  184. #endif