]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 1998-2003 Joel de Guzman | |
3 | Copyright (c) 2003 Vaclav Vesely | |
4 | http://spirit.sourceforge.net/ | |
5 | ||
6 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | =============================================================================*/ | |
9 | #if !defined(BOOST_SPIRIT_DISTINCT_HPP) | |
10 | #define BOOST_SPIRIT_DISTINCT_HPP | |
11 | ||
12 | #include <boost/spirit/home/classic/core/parser.hpp> | |
13 | #include <boost/spirit/home/classic/core/primitives/primitives.hpp> | |
14 | #include <boost/spirit/home/classic/core/composite/operators.hpp> | |
15 | #include <boost/spirit/home/classic/core/composite/directives.hpp> | |
16 | #include <boost/spirit/home/classic/core/composite/epsilon.hpp> | |
17 | #include <boost/spirit/home/classic/core/non_terminal/rule.hpp> | |
18 | #include <boost/spirit/home/classic/utility/chset.hpp> | |
19 | ||
20 | #include <boost/spirit/home/classic/utility/distinct_fwd.hpp> | |
21 | ||
22 | namespace boost { | |
23 | namespace spirit { | |
24 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
25 | ||
26 | //----------------------------------------------------------------------------- | |
27 | // distinct_parser class | |
28 | ||
29 | template <typename CharT, typename TailT> | |
30 | class distinct_parser | |
31 | { | |
32 | public: | |
33 | typedef | |
34 | contiguous< | |
35 | sequence< | |
36 | chseq<CharT const*>, | |
37 | negated_empty_match_parser< | |
38 | TailT | |
39 | > | |
40 | > | |
41 | > | |
42 | result_t; | |
43 | ||
44 | distinct_parser() | |
45 | : tail(chset<CharT>()) | |
46 | { | |
47 | } | |
48 | ||
49 | explicit distinct_parser(parser<TailT> const & tail_) | |
50 | : tail(tail_.derived()) | |
51 | { | |
52 | } | |
53 | ||
54 | explicit distinct_parser(CharT const* letters) | |
55 | : tail(chset_p(letters)) | |
56 | { | |
57 | } | |
58 | ||
59 | result_t operator()(CharT const* str) const | |
60 | { | |
61 | return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; | |
62 | } | |
63 | ||
64 | TailT tail; | |
65 | }; | |
66 | ||
67 | //----------------------------------------------------------------------------- | |
68 | // distinct_directive class | |
69 | ||
70 | template <typename CharT, typename TailT> | |
71 | class distinct_directive | |
72 | { | |
73 | public: | |
74 | template<typename ParserT> | |
75 | struct result { | |
76 | typedef | |
77 | contiguous< | |
78 | sequence< | |
79 | ParserT, | |
80 | negated_empty_match_parser< | |
81 | TailT | |
82 | > | |
83 | > | |
84 | > | |
85 | type; | |
86 | }; | |
87 | ||
88 | distinct_directive() | |
89 | : tail(chset<CharT>()) | |
90 | { | |
91 | } | |
92 | ||
93 | explicit distinct_directive(CharT const* letters) | |
94 | : tail(chset_p(letters)) | |
95 | { | |
96 | } | |
97 | ||
98 | explicit distinct_directive(parser<TailT> const & tail_) | |
99 | : tail(tail_.derived()) | |
100 | { | |
101 | } | |
102 | ||
103 | template<typename ParserT> | |
104 | typename result<typename as_parser<ParserT>::type>::type | |
105 | operator[](ParserT const &subject) const | |
106 | { | |
107 | return | |
108 | lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; | |
109 | } | |
110 | ||
111 | TailT tail; | |
112 | }; | |
113 | ||
114 | //----------------------------------------------------------------------------- | |
115 | // dynamic_distinct_parser class | |
116 | ||
117 | template <typename ScannerT> | |
118 | class dynamic_distinct_parser | |
119 | { | |
120 | public: | |
121 | typedef typename ScannerT::value_t char_t; | |
122 | ||
123 | typedef | |
124 | rule< | |
125 | typename no_actions_scanner< | |
126 | typename lexeme_scanner<ScannerT>::type | |
127 | >::type | |
128 | > | |
129 | tail_t; | |
130 | ||
131 | typedef | |
132 | contiguous< | |
133 | sequence< | |
134 | chseq<char_t const*>, | |
135 | negated_empty_match_parser< | |
136 | tail_t | |
137 | > | |
138 | > | |
139 | > | |
140 | result_t; | |
141 | ||
142 | dynamic_distinct_parser() | |
143 | : tail(nothing_p) | |
144 | { | |
145 | } | |
146 | ||
147 | template<typename ParserT> | |
148 | explicit dynamic_distinct_parser(parser<ParserT> const & tail_) | |
149 | : tail(tail_.derived()) | |
150 | { | |
151 | } | |
152 | ||
153 | explicit dynamic_distinct_parser(char_t const* letters) | |
154 | : tail(chset_p(letters)) | |
155 | { | |
156 | } | |
157 | ||
158 | result_t operator()(char_t const* str) const | |
159 | { | |
160 | return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)]; | |
161 | } | |
162 | ||
163 | tail_t tail; | |
164 | }; | |
165 | ||
166 | //----------------------------------------------------------------------------- | |
167 | // dynamic_distinct_directive class | |
168 | ||
169 | template <typename ScannerT> | |
170 | class dynamic_distinct_directive | |
171 | { | |
172 | public: | |
173 | typedef typename ScannerT::value_t char_t; | |
174 | ||
175 | typedef | |
176 | rule< | |
177 | typename no_actions_scanner< | |
178 | typename lexeme_scanner<ScannerT>::type | |
179 | >::type | |
180 | > | |
181 | tail_t; | |
182 | ||
183 | template<typename ParserT> | |
184 | struct result { | |
185 | typedef | |
186 | contiguous< | |
187 | sequence< | |
188 | ParserT, | |
189 | negated_empty_match_parser< | |
190 | tail_t | |
191 | > | |
192 | > | |
193 | > | |
194 | type; | |
195 | }; | |
196 | ||
197 | dynamic_distinct_directive() | |
198 | : tail(nothing_p) | |
199 | { | |
200 | } | |
201 | ||
202 | template<typename ParserT> | |
203 | explicit dynamic_distinct_directive(parser<ParserT> const & tail_) | |
204 | : tail(tail_.derived()) | |
205 | { | |
206 | } | |
207 | ||
208 | explicit dynamic_distinct_directive(char_t const* letters) | |
209 | : tail(chset_p(letters)) | |
210 | { | |
211 | } | |
212 | ||
213 | template<typename ParserT> | |
214 | typename result<typename as_parser<ParserT>::type>::type | |
215 | operator[](ParserT const &subject) const | |
216 | { | |
217 | return | |
218 | lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)]; | |
219 | } | |
220 | ||
221 | tail_t tail; | |
222 | }; | |
223 | ||
224 | //----------------------------------------------------------------------------- | |
225 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
226 | } // namespace spirit | |
227 | } // namespace boost | |
228 | ||
229 | #endif // !defined(BOOST_SPIRIT_DISTINCT_HPP) |