1 /*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
13 #include <boost/spirit/home/classic/meta/refactoring.hpp>
15 ///////////////////////////////////////////////////////////////////////////////
16 namespace boost { namespace spirit {
18 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
20 ///////////////////////////////////////////////////////////////////////////////
22 // list_parser_type class implementation
24 ///////////////////////////////////////////////////////////////////////////////
25 struct no_list_endtoken { typedef no_list_endtoken embed_t; };
29 ///////////////////////////////////////////////////////////////////////////////
31 // Refactor the original list item parser
33 ///////////////////////////////////////////////////////////////////////////////
35 // match list with 'extended' syntax
36 template <typename EndT>
37 struct select_list_parse_refactor {
40 typename ParserT, typename ScannerT,
41 typename ItemT, typename DelimT
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)
47 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
48 const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
51 refactor_item_d[item - (end | delim)]
52 >> *(delim >> refactor_item_d[item - (end | delim)])
58 // match list with 'normal' syntax (without an 'end' parser)
60 struct select_list_parse_refactor<no_list_endtoken> {
63 typename ParserT, typename ScannerT,
64 typename ItemT, typename DelimT
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&)
70 typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
71 const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
74 refactor_item_d[item - delim]
75 >> *(delim >> refactor_item_d[item - delim])
80 ///////////////////////////////////////////////////////////////////////////////
82 // Do not refactor the original list item parser.
84 ///////////////////////////////////////////////////////////////////////////////
86 // match list with 'extended' syntax
87 template <typename EndT>
88 struct select_list_parse_no_refactor {
91 typename ParserT, typename ScannerT,
92 typename ItemT, typename DelimT
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)
99 (item - (end | delim))
100 >> *(delim >> (item - (end | delim)))
106 // match list with 'normal' syntax (without an 'end' parser)
108 struct select_list_parse_no_refactor<no_list_endtoken> {
111 typename ParserT, typename ScannerT,
112 typename ItemT, typename DelimT
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&)
120 >> *(delim >> (item - delim))
125 // the refactoring is handled by the refactoring parsers, so here there
126 // is no need to pay attention to these issues.
128 template <typename CategoryT>
129 struct list_parser_type {
132 typename ParserT, typename ScannerT,
133 typename ItemT, typename DelimT, typename EndT
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)
139 return select_list_parse_refactor<EndT>::
140 parse(scan, p, item, delim, end);
145 struct list_parser_type<plain_parser_category> {
148 typename ParserT, typename ScannerT,
149 typename ItemT, typename DelimT, typename EndT
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)
155 return select_list_parse_no_refactor<EndT>::
156 parse(scan, p, item, delim, end);
162 ///////////////////////////////////////////////////////////////////////////////
163 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
165 }} // namespace boost::spirit