]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | /////////////////////////////////////////////////////////////////////////////// | |
16 | namespace boost { namespace spirit { | |
17 | ||
18 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
19 | ||
20 | /////////////////////////////////////////////////////////////////////////////// | |
21 | // | |
22 | // list_parser_type class implementation | |
23 | // | |
24 | /////////////////////////////////////////////////////////////////////////////// | |
25 | struct no_list_endtoken { typedef no_list_endtoken embed_t; }; | |
26 | ||
27 | namespace 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 | /////////////////////////////////////////////////////////////////////////////// | |
163 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
164 | ||
165 | }} // namespace boost::spirit | |
166 | ||
167 | #endif | |
168 |