1/*============================================================================= 2 Copyright (c) 2002-2003 Hartmut Kaiser 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8=============================================================================*/ 9#ifndef BOOST_SPIRIT_LISTS_IPP 10#define BOOST_SPIRIT_LISTS_IPP 11 12/////////////////////////////////////////////////////////////////////////////// 13#include <boost/spirit/home/classic/meta/refactoring.hpp> 14 15/////////////////////////////////////////////////////////////////////////////// 16namespace boost { namespace spirit { 17 18BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 19 20/////////////////////////////////////////////////////////////////////////////// 21// 22// list_parser_type class implementation 23// 24/////////////////////////////////////////////////////////////////////////////// 25struct no_list_endtoken { typedef no_list_endtoken embed_t; }; 26 27namespace impl { 28 29/////////////////////////////////////////////////////////////////////////////// 30// 31// Refactor the original list item parser 32// 33/////////////////////////////////////////////////////////////////////////////// 34 35 // match list with 'extended' syntax 36 template <typename EndT> 37 struct select_list_parse_refactor { 38 39 template < 40 typename ParserT, typename ScannerT, 41 typename ItemT, typename DelimT 42 > 43 static typename parser_result<ParserT, ScannerT>::type 44 parse(ScannerT const& scan, ParserT const& /*p*/, 45 ItemT const &item, DelimT const &delim, EndT const &end) 46 { 47 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; 48 const refactor_t refactor_item_d = refactor_t(refactor_unary_d); 49 50 return ( 51 refactor_item_d[item - (end | delim)] 52 >> *(delim >> refactor_item_d[item - (end | delim)]) 53 >> !(delim >> end) 54 ).parse(scan); 55 } 56 }; 57 58 // match list with 'normal' syntax (without an 'end' parser) 59 template <> 60 struct select_list_parse_refactor<no_list_endtoken> { 61 62 template < 63 typename ParserT, typename ScannerT, 64 typename ItemT, typename DelimT 65 > 66 static typename parser_result<ParserT, ScannerT>::type 67 parse(ScannerT const& scan, ParserT const& /*p*/, 68 ItemT const &item, DelimT const &delim, no_list_endtoken const&) 69 { 70 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t; 71 const refactor_t refactor_item_d = refactor_t(refactor_unary_d); 72 73 return ( 74 refactor_item_d[item - delim] 75 >> *(delim >> refactor_item_d[item - delim]) 76 ).parse(scan); 77 } 78 }; 79 80/////////////////////////////////////////////////////////////////////////////// 81// 82// Do not refactor the original list item parser. 83// 84/////////////////////////////////////////////////////////////////////////////// 85 86 // match list with 'extended' syntax 87 template <typename EndT> 88 struct select_list_parse_no_refactor { 89 90 template < 91 typename ParserT, typename ScannerT, 92 typename ItemT, typename DelimT 93 > 94 static typename parser_result<ParserT, ScannerT>::type 95 parse(ScannerT const& scan, ParserT const& /*p*/, 96 ItemT const &item, DelimT const &delim, EndT const &end) 97 { 98 return ( 99 (item - (end | delim)) 100 >> *(delim >> (item - (end | delim))) 101 >> !(delim >> end) 102 ).parse(scan); 103 } 104 }; 105 106 // match list with 'normal' syntax (without an 'end' parser) 107 template <> 108 struct select_list_parse_no_refactor<no_list_endtoken> { 109 110 template < 111 typename ParserT, typename ScannerT, 112 typename ItemT, typename DelimT 113 > 114 static typename parser_result<ParserT, ScannerT>::type 115 parse(ScannerT const& scan, ParserT const& /*p*/, 116 ItemT const &item, DelimT const &delim, no_list_endtoken const&) 117 { 118 return ( 119 (item - delim) 120 >> *(delim >> (item - delim)) 121 ).parse(scan); 122 } 123 }; 124 125 // the refactoring is handled by the refactoring parsers, so here there 126 // is no need to pay attention to these issues. 127 128 template <typename CategoryT> 129 struct list_parser_type { 130 131 template < 132 typename ParserT, typename ScannerT, 133 typename ItemT, typename DelimT, typename EndT 134 > 135 static typename parser_result<ParserT, ScannerT>::type 136 parse(ScannerT const& scan, ParserT const& p, 137 ItemT const &item, DelimT const &delim, EndT const &end) 138 { 139 return select_list_parse_refactor<EndT>:: 140 parse(scan, p, item, delim, end); 141 } 142 }; 143 144 template <> 145 struct list_parser_type<plain_parser_category> { 146 147 template < 148 typename ParserT, typename ScannerT, 149 typename ItemT, typename DelimT, typename EndT 150 > 151 static typename parser_result<ParserT, ScannerT>::type 152 parse(ScannerT const& scan, ParserT const& p, 153 ItemT const &item, DelimT const &delim, EndT const &end) 154 { 155 return select_list_parse_no_refactor<EndT>:: 156 parse(scan, p, item, delim, end); 157 } 158 }; 159 160} // namespace impl 161 162/////////////////////////////////////////////////////////////////////////////// 163BOOST_SPIRIT_CLASSIC_NAMESPACE_END 164 165}} // namespace boost::spirit 166 167#endif 168 169