9
3

lists.ipp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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_LISTS_IPP
  9. #define BOOST_SPIRIT_LISTS_IPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include <boost/spirit/home/classic/meta/refactoring.hpp>
  12. ///////////////////////////////////////////////////////////////////////////////
  13. namespace boost { namespace spirit {
  14. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. // list_parser_type class implementation
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. struct no_list_endtoken { typedef no_list_endtoken embed_t; };
  21. namespace impl {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Refactor the original list item parser
  25. //
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // match list with 'extended' syntax
  28. template <typename EndT>
  29. struct select_list_parse_refactor {
  30. template <
  31. typename ParserT, typename ScannerT,
  32. typename ItemT, typename DelimT
  33. >
  34. static typename parser_result<ParserT, ScannerT>::type
  35. parse(ScannerT const& scan, ParserT const& /*p*/,
  36. ItemT const &item, DelimT const &delim, EndT const &end)
  37. {
  38. typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
  39. const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
  40. return (
  41. refactor_item_d[item - (end | delim)]
  42. >> *(delim >> refactor_item_d[item - (end | delim)])
  43. >> !(delim >> end)
  44. ).parse(scan);
  45. }
  46. };
  47. // match list with 'normal' syntax (without an 'end' parser)
  48. template <>
  49. struct select_list_parse_refactor<no_list_endtoken> {
  50. template <
  51. typename ParserT, typename ScannerT,
  52. typename ItemT, typename DelimT
  53. >
  54. static typename parser_result<ParserT, ScannerT>::type
  55. parse(ScannerT const& scan, ParserT const& /*p*/,
  56. ItemT const &item, DelimT const &delim, no_list_endtoken const&)
  57. {
  58. typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
  59. const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
  60. return (
  61. refactor_item_d[item - delim]
  62. >> *(delim >> refactor_item_d[item - delim])
  63. ).parse(scan);
  64. }
  65. };
  66. ///////////////////////////////////////////////////////////////////////////////
  67. //
  68. // Do not refactor the original list item parser.
  69. //
  70. ///////////////////////////////////////////////////////////////////////////////
  71. // match list with 'extended' syntax
  72. template <typename EndT>
  73. struct select_list_parse_no_refactor {
  74. template <
  75. typename ParserT, typename ScannerT,
  76. typename ItemT, typename DelimT
  77. >
  78. static typename parser_result<ParserT, ScannerT>::type
  79. parse(ScannerT const& scan, ParserT const& /*p*/,
  80. ItemT const &item, DelimT const &delim, EndT const &end)
  81. {
  82. return (
  83. (item - (end | delim))
  84. >> *(delim >> (item - (end | delim)))
  85. >> !(delim >> end)
  86. ).parse(scan);
  87. }
  88. };
  89. // match list with 'normal' syntax (without an 'end' parser)
  90. template <>
  91. struct select_list_parse_no_refactor<no_list_endtoken> {
  92. template <
  93. typename ParserT, typename ScannerT,
  94. typename ItemT, typename DelimT
  95. >
  96. static typename parser_result<ParserT, ScannerT>::type
  97. parse(ScannerT const& scan, ParserT const& /*p*/,
  98. ItemT const &item, DelimT const &delim, no_list_endtoken const&)
  99. {
  100. return (
  101. (item - delim)
  102. >> *(delim >> (item - delim))
  103. ).parse(scan);
  104. }
  105. };
  106. // the refactoring is handled by the refactoring parsers, so here there
  107. // is no need to pay attention to these issues.
  108. template <typename CategoryT>
  109. struct list_parser_type {
  110. template <
  111. typename ParserT, typename ScannerT,
  112. typename ItemT, typename DelimT, typename EndT
  113. >
  114. static typename parser_result<ParserT, ScannerT>::type
  115. parse(ScannerT const& scan, ParserT const& p,
  116. ItemT const &item, DelimT const &delim, EndT const &end)
  117. {
  118. return select_list_parse_refactor<EndT>::
  119. parse(scan, p, item, delim, end);
  120. }
  121. };
  122. template <>
  123. struct list_parser_type<plain_parser_category> {
  124. template <
  125. typename ParserT, typename ScannerT,
  126. typename ItemT, typename DelimT, typename EndT
  127. >
  128. static typename parser_result<ParserT, ScannerT>::type
  129. parse(ScannerT const& scan, ParserT const& p,
  130. ItemT const &item, DelimT const &delim, EndT const &end)
  131. {
  132. return select_list_parse_no_refactor<EndT>::
  133. parse(scan, p, item, delim, end);
  134. }
  135. };
  136. } // namespace impl
  137. ///////////////////////////////////////////////////////////////////////////////
  138. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  139. }} // namespace boost::spirit
  140. #endif