Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file regex_primitives.hpp
|
Chris@16
|
3 /// Contains the syntax elements for writing static regular expressions.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_XPRESSIVE_REGEX_PRIMITIVES_HPP_EAN_10_04_2005
|
Chris@16
|
10 #define BOOST_XPRESSIVE_REGEX_PRIMITIVES_HPP_EAN_10_04_2005
|
Chris@16
|
11
|
Chris@16
|
12 #include <vector>
|
Chris@16
|
13 #include <climits>
|
Chris@16
|
14 #include <boost/config.hpp>
|
Chris@16
|
15 #include <boost/assert.hpp>
|
Chris@16
|
16 #include <boost/mpl/if.hpp>
|
Chris@16
|
17 #include <boost/mpl/and.hpp>
|
Chris@16
|
18 #include <boost/mpl/assert.hpp>
|
Chris@16
|
19 #include <boost/detail/workaround.hpp>
|
Chris@16
|
20 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
21 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
22 #include <boost/xpressive/detail/core/matchers.hpp>
|
Chris@16
|
23 #include <boost/xpressive/detail/core/regex_domain.hpp>
|
Chris@16
|
24 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 // Doxygen can't handle proto :-(
|
Chris@16
|
27 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
|
Chris@16
|
28 # include <boost/proto/core.hpp>
|
Chris@16
|
29 # include <boost/proto/transform/arg.hpp>
|
Chris@16
|
30 # include <boost/proto/transform/when.hpp>
|
Chris@16
|
31 # include <boost/xpressive/detail/core/icase.hpp>
|
Chris@16
|
32 # include <boost/xpressive/detail/static/compile.hpp>
|
Chris@16
|
33 # include <boost/xpressive/detail/static/modifier.hpp>
|
Chris@16
|
34 #endif
|
Chris@16
|
35
|
Chris@16
|
36 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
37 {
|
Chris@16
|
38
|
Chris@16
|
39 typedef assert_word_placeholder<word_boundary<mpl::true_> > assert_word_boundary;
|
Chris@16
|
40 typedef assert_word_placeholder<word_begin> assert_word_begin;
|
Chris@16
|
41 typedef assert_word_placeholder<word_end> assert_word_end;
|
Chris@16
|
42
|
Chris@16
|
43 // workaround msvc-7.1 bug with function pointer types
|
Chris@16
|
44 // within function types:
|
Chris@16
|
45 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
Chris@16
|
46 #define mark_number(x) proto::call<mark_number(x)>
|
Chris@16
|
47 #define minus_one() proto::make<minus_one()>
|
Chris@16
|
48 #endif
|
Chris@16
|
49
|
Chris@16
|
50 struct push_back : proto::callable
|
Chris@16
|
51 {
|
Chris@16
|
52 typedef int result_type;
|
Chris@16
|
53
|
Chris@16
|
54 template<typename Subs>
|
Chris@16
|
55 int operator ()(Subs &subs, int i) const
|
Chris@16
|
56 {
|
Chris@16
|
57 subs.push_back(i);
|
Chris@16
|
58 return i;
|
Chris@16
|
59 }
|
Chris@16
|
60 };
|
Chris@16
|
61
|
Chris@16
|
62 struct mark_number : proto::callable
|
Chris@16
|
63 {
|
Chris@16
|
64 typedef int result_type;
|
Chris@16
|
65
|
Chris@16
|
66 template<typename Expr>
|
Chris@16
|
67 int operator ()(Expr const &expr) const
|
Chris@16
|
68 {
|
Chris@16
|
69 return expr.mark_number_;
|
Chris@16
|
70 }
|
Chris@16
|
71 };
|
Chris@16
|
72
|
Chris@16
|
73 typedef mpl::int_<-1> minus_one;
|
Chris@16
|
74
|
Chris@16
|
75 // s1 or -s1
|
Chris@16
|
76 struct SubMatch
|
Chris@16
|
77 : proto::or_<
|
Chris@16
|
78 proto::when<basic_mark_tag, push_back(proto::_data, mark_number(proto::_value)) >
|
Chris@16
|
79 , proto::when<proto::negate<basic_mark_tag>, push_back(proto::_data, minus_one()) >
|
Chris@16
|
80 >
|
Chris@16
|
81 {};
|
Chris@16
|
82
|
Chris@16
|
83 struct SubMatchList
|
Chris@16
|
84 : proto::or_<SubMatch, proto::comma<SubMatchList, SubMatch> >
|
Chris@16
|
85 {};
|
Chris@16
|
86
|
Chris@16
|
87 template<typename Subs>
|
Chris@16
|
88 typename enable_if<
|
Chris@16
|
89 mpl::and_<proto::is_expr<Subs>, proto::matches<Subs, SubMatchList> >
|
Chris@16
|
90 , std::vector<int>
|
Chris@16
|
91 >::type
|
Chris@16
|
92 to_vector(Subs const &subs)
|
Chris@16
|
93 {
|
Chris@16
|
94 std::vector<int> subs_;
|
Chris@16
|
95 SubMatchList()(subs, 0, subs_);
|
Chris@16
|
96 return subs_;
|
Chris@16
|
97 }
|
Chris@16
|
98
|
Chris@16
|
99 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
Chris@16
|
100 #undef mark_number
|
Chris@16
|
101 #undef minus_one
|
Chris@16
|
102 #endif
|
Chris@16
|
103
|
Chris@16
|
104 // replace "Expr" with "keep(*State) >> Expr"
|
Chris@16
|
105 struct skip_primitives : proto::transform<skip_primitives>
|
Chris@16
|
106 {
|
Chris@16
|
107 template<typename Expr, typename State, typename Data>
|
Chris@16
|
108 struct impl : proto::transform_impl<Expr, State, Data>
|
Chris@16
|
109 {
|
Chris@16
|
110 typedef
|
Chris@16
|
111 typename proto::shift_right<
|
Chris@16
|
112 typename proto::unary_expr<
|
Chris@16
|
113 keeper_tag
|
Chris@16
|
114 , typename proto::dereference<State>::type
|
Chris@16
|
115 >::type
|
Chris@16
|
116 , Expr
|
Chris@16
|
117 >::type
|
Chris@16
|
118 result_type;
|
Chris@16
|
119
|
Chris@16
|
120 result_type operator ()(
|
Chris@16
|
121 typename impl::expr_param expr
|
Chris@16
|
122 , typename impl::state_param state
|
Chris@16
|
123 , typename impl::data_param
|
Chris@16
|
124 ) const
|
Chris@16
|
125 {
|
Chris@16
|
126 result_type that = {{{state}}, expr};
|
Chris@16
|
127 return that;
|
Chris@16
|
128 }
|
Chris@16
|
129 };
|
Chris@16
|
130 };
|
Chris@16
|
131
|
Chris@16
|
132 struct Primitives
|
Chris@16
|
133 : proto::or_<
|
Chris@16
|
134 proto::terminal<proto::_>
|
Chris@16
|
135 , proto::comma<proto::_, proto::_>
|
Chris@16
|
136 , proto::subscript<proto::terminal<set_initializer>, proto::_>
|
Chris@16
|
137 , proto::assign<proto::terminal<set_initializer>, proto::_>
|
Chris@16
|
138 , proto::assign<proto::terminal<attribute_placeholder<proto::_> >, proto::_>
|
Chris@16
|
139 , proto::complement<Primitives>
|
Chris@16
|
140 >
|
Chris@16
|
141 {};
|
Chris@16
|
142
|
Chris@16
|
143 struct SkipGrammar
|
Chris@16
|
144 : proto::or_<
|
Chris@16
|
145 proto::when<Primitives, skip_primitives>
|
Chris@16
|
146 , proto::assign<proto::terminal<mark_placeholder>, SkipGrammar> // don't "skip" mark tags
|
Chris@16
|
147 , proto::subscript<SkipGrammar, proto::_> // don't put skips in actions
|
Chris@16
|
148 , proto::binary_expr<modifier_tag, proto::_, SkipGrammar> // don't skip modifiers
|
Chris@16
|
149 , proto::unary_expr<lookbehind_tag, proto::_> // don't skip lookbehinds
|
Chris@16
|
150 , proto::nary_expr<proto::_, proto::vararg<SkipGrammar> > // everything else is fair game!
|
Chris@16
|
151 >
|
Chris@16
|
152 {};
|
Chris@16
|
153
|
Chris@16
|
154 template<typename Skip>
|
Chris@16
|
155 struct skip_directive
|
Chris@16
|
156 {
|
Chris@16
|
157 typedef typename proto::result_of::as_expr<Skip>::type skip_type;
|
Chris@16
|
158
|
Chris@16
|
159 skip_directive(Skip const &skip)
|
Chris@16
|
160 : skip_(proto::as_expr(skip))
|
Chris@16
|
161 {}
|
Chris@16
|
162
|
Chris@16
|
163 template<typename Sig>
|
Chris@16
|
164 struct result {};
|
Chris@16
|
165
|
Chris@16
|
166 template<typename This, typename Expr>
|
Chris@16
|
167 struct result<This(Expr)>
|
Chris@16
|
168 {
|
Chris@16
|
169 typedef
|
Chris@16
|
170 SkipGrammar::impl<
|
Chris@16
|
171 typename proto::result_of::as_expr<Expr>::type
|
Chris@16
|
172 , skip_type const &
|
Chris@16
|
173 , mpl::void_ &
|
Chris@16
|
174 >
|
Chris@16
|
175 skip_transform;
|
Chris@16
|
176
|
Chris@16
|
177 typedef
|
Chris@16
|
178 typename proto::shift_right<
|
Chris@16
|
179 typename skip_transform::result_type
|
Chris@16
|
180 , typename proto::dereference<skip_type>::type
|
Chris@16
|
181 >::type
|
Chris@16
|
182 type;
|
Chris@16
|
183 };
|
Chris@16
|
184
|
Chris@16
|
185 template<typename Expr>
|
Chris@16
|
186 typename result<skip_directive(Expr)>::type
|
Chris@16
|
187 operator ()(Expr const &expr) const
|
Chris@16
|
188 {
|
Chris@16
|
189 mpl::void_ ignore;
|
Chris@16
|
190 typedef result<skip_directive(Expr)> result_fun;
|
Chris@16
|
191 typename result_fun::type that = {
|
Chris@16
|
192 typename result_fun::skip_transform()(proto::as_expr(expr), this->skip_, ignore)
|
Chris@16
|
193 , {skip_}
|
Chris@16
|
194 };
|
Chris@16
|
195 return that;
|
Chris@16
|
196 }
|
Chris@16
|
197
|
Chris@16
|
198 private:
|
Chris@16
|
199 skip_type skip_;
|
Chris@16
|
200 };
|
Chris@16
|
201
|
Chris@16
|
202 /*
|
Chris@16
|
203 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
204 /// INTERNAL ONLY
|
Chris@16
|
205 // BOOST_XPRESSIVE_GLOBAL
|
Chris@16
|
206 // for defining globals that neither violate the One Definition Rule nor
|
Chris@16
|
207 // lead to undefined behavior due to global object initialization order.
|
Chris@16
|
208 //#define BOOST_XPRESSIVE_GLOBAL(type, name, init) \
|
Chris@16
|
209 // namespace detail \
|
Chris@16
|
210 // { \
|
Chris@16
|
211 // template<int Dummy> \
|
Chris@16
|
212 // struct BOOST_PP_CAT(global_pod_, name) \
|
Chris@16
|
213 // { \
|
Chris@16
|
214 // static type const value; \
|
Chris@16
|
215 // private: \
|
Chris@16
|
216 // union type_must_be_pod \
|
Chris@16
|
217 // { \
|
Chris@16
|
218 // type t; \
|
Chris@16
|
219 // char ch; \
|
Chris@16
|
220 // } u; \
|
Chris@16
|
221 // }; \
|
Chris@16
|
222 // template<int Dummy> \
|
Chris@16
|
223 // type const BOOST_PP_CAT(global_pod_, name)<Dummy>::value = init; \
|
Chris@16
|
224 // } \
|
Chris@16
|
225 // type const &name = detail::BOOST_PP_CAT(global_pod_, name)<0>::value
|
Chris@16
|
226 */
|
Chris@16
|
227
|
Chris@16
|
228
|
Chris@16
|
229 } // namespace detail
|
Chris@16
|
230
|
Chris@16
|
231 /// INTERNAL ONLY (for backwards compatibility)
|
Chris@16
|
232 unsigned int const repeat_max = UINT_MAX-1;
|
Chris@16
|
233
|
Chris@16
|
234 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
235 /// \brief For infinite repetition of a sub-expression.
|
Chris@16
|
236 ///
|
Chris@16
|
237 /// Magic value used with the repeat\<\>() function template
|
Chris@16
|
238 /// to specify an unbounded repeat. Use as: repeat<17, inf>('a').
|
Chris@16
|
239 /// The equivalent in perl is /a{17,}/.
|
Chris@16
|
240 unsigned int const inf = UINT_MAX-1;
|
Chris@16
|
241
|
Chris@16
|
242 /// INTERNAL ONLY (for backwards compatibility)
|
Chris@16
|
243 proto::terminal<detail::epsilon_matcher>::type const epsilon = {{}};
|
Chris@16
|
244
|
Chris@16
|
245 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
246 /// \brief Successfully matches nothing.
|
Chris@16
|
247 ///
|
Chris@16
|
248 /// Successfully matches a zero-width sequence. nil always succeeds and
|
Chris@16
|
249 /// never consumes any characters.
|
Chris@16
|
250 proto::terminal<detail::epsilon_matcher>::type const nil = {{}};
|
Chris@16
|
251
|
Chris@16
|
252 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
253 /// \brief Matches an alpha-numeric character.
|
Chris@16
|
254 ///
|
Chris@16
|
255 /// The regex traits are used to determine which characters are alpha-numeric.
|
Chris@16
|
256 /// To match any character that is not alpha-numeric, use ~alnum.
|
Chris@16
|
257 ///
|
Chris@16
|
258 /// \attention alnum is equivalent to /[[:alnum:]]/ in perl. ~alnum is equivalent
|
Chris@16
|
259 /// to /[[:^alnum:]]/ in perl.
|
Chris@16
|
260 proto::terminal<detail::posix_charset_placeholder>::type const alnum = {{"alnum", false}};
|
Chris@16
|
261
|
Chris@16
|
262 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
263 /// \brief Matches an alphabetic character.
|
Chris@16
|
264 ///
|
Chris@16
|
265 /// The regex traits are used to determine which characters are alphabetic.
|
Chris@16
|
266 /// To match any character that is not alphabetic, use ~alpha.
|
Chris@16
|
267 ///
|
Chris@16
|
268 /// \attention alpha is equivalent to /[[:alpha:]]/ in perl. ~alpha is equivalent
|
Chris@16
|
269 /// to /[[:^alpha:]]/ in perl.
|
Chris@16
|
270 proto::terminal<detail::posix_charset_placeholder>::type const alpha = {{"alpha", false}};
|
Chris@16
|
271
|
Chris@16
|
272 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
273 /// \brief Matches a blank (horizonal white-space) character.
|
Chris@16
|
274 ///
|
Chris@16
|
275 /// The regex traits are used to determine which characters are blank characters.
|
Chris@16
|
276 /// To match any character that is not blank, use ~blank.
|
Chris@16
|
277 ///
|
Chris@16
|
278 /// \attention blank is equivalent to /[[:blank:]]/ in perl. ~blank is equivalent
|
Chris@16
|
279 /// to /[[:^blank:]]/ in perl.
|
Chris@16
|
280 proto::terminal<detail::posix_charset_placeholder>::type const blank = {{"blank", false}};
|
Chris@16
|
281
|
Chris@16
|
282 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
283 /// \brief Matches a control character.
|
Chris@16
|
284 ///
|
Chris@16
|
285 /// The regex traits are used to determine which characters are control characters.
|
Chris@16
|
286 /// To match any character that is not a control character, use ~cntrl.
|
Chris@16
|
287 ///
|
Chris@16
|
288 /// \attention cntrl is equivalent to /[[:cntrl:]]/ in perl. ~cntrl is equivalent
|
Chris@16
|
289 /// to /[[:^cntrl:]]/ in perl.
|
Chris@16
|
290 proto::terminal<detail::posix_charset_placeholder>::type const cntrl = {{"cntrl", false}};
|
Chris@16
|
291
|
Chris@16
|
292 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
293 /// \brief Matches a digit character.
|
Chris@16
|
294 ///
|
Chris@16
|
295 /// The regex traits are used to determine which characters are digits.
|
Chris@16
|
296 /// To match any character that is not a digit, use ~digit.
|
Chris@16
|
297 ///
|
Chris@16
|
298 /// \attention digit is equivalent to /[[:digit:]]/ in perl. ~digit is equivalent
|
Chris@16
|
299 /// to /[[:^digit:]]/ in perl.
|
Chris@16
|
300 proto::terminal<detail::posix_charset_placeholder>::type const digit = {{"digit", false}};
|
Chris@16
|
301
|
Chris@16
|
302 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
303 /// \brief Matches a graph character.
|
Chris@16
|
304 ///
|
Chris@16
|
305 /// The regex traits are used to determine which characters are graphable.
|
Chris@16
|
306 /// To match any character that is not graphable, use ~graph.
|
Chris@16
|
307 ///
|
Chris@16
|
308 /// \attention graph is equivalent to /[[:graph:]]/ in perl. ~graph is equivalent
|
Chris@16
|
309 /// to /[[:^graph:]]/ in perl.
|
Chris@16
|
310 proto::terminal<detail::posix_charset_placeholder>::type const graph = {{"graph", false}};
|
Chris@16
|
311
|
Chris@16
|
312 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
313 /// \brief Matches a lower-case character.
|
Chris@16
|
314 ///
|
Chris@16
|
315 /// The regex traits are used to determine which characters are lower-case.
|
Chris@16
|
316 /// To match any character that is not a lower-case character, use ~lower.
|
Chris@16
|
317 ///
|
Chris@16
|
318 /// \attention lower is equivalent to /[[:lower:]]/ in perl. ~lower is equivalent
|
Chris@16
|
319 /// to /[[:^lower:]]/ in perl.
|
Chris@16
|
320 proto::terminal<detail::posix_charset_placeholder>::type const lower = {{"lower", false}};
|
Chris@16
|
321
|
Chris@16
|
322 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
323 /// \brief Matches a printable character.
|
Chris@16
|
324 ///
|
Chris@16
|
325 /// The regex traits are used to determine which characters are printable.
|
Chris@16
|
326 /// To match any character that is not printable, use ~print.
|
Chris@16
|
327 ///
|
Chris@16
|
328 /// \attention print is equivalent to /[[:print:]]/ in perl. ~print is equivalent
|
Chris@16
|
329 /// to /[[:^print:]]/ in perl.
|
Chris@16
|
330 proto::terminal<detail::posix_charset_placeholder>::type const print = {{"print", false}};
|
Chris@16
|
331
|
Chris@16
|
332 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
333 /// \brief Matches a punctuation character.
|
Chris@16
|
334 ///
|
Chris@16
|
335 /// The regex traits are used to determine which characters are punctuation.
|
Chris@16
|
336 /// To match any character that is not punctuation, use ~punct.
|
Chris@16
|
337 ///
|
Chris@16
|
338 /// \attention punct is equivalent to /[[:punct:]]/ in perl. ~punct is equivalent
|
Chris@16
|
339 /// to /[[:^punct:]]/ in perl.
|
Chris@16
|
340 proto::terminal<detail::posix_charset_placeholder>::type const punct = {{"punct", false}};
|
Chris@16
|
341
|
Chris@16
|
342 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
343 /// \brief Matches a space character.
|
Chris@16
|
344 ///
|
Chris@16
|
345 /// The regex traits are used to determine which characters are space characters.
|
Chris@16
|
346 /// To match any character that is not white-space, use ~space.
|
Chris@16
|
347 ///
|
Chris@16
|
348 /// \attention space is equivalent to /[[:space:]]/ in perl. ~space is equivalent
|
Chris@16
|
349 /// to /[[:^space:]]/ in perl.
|
Chris@16
|
350 proto::terminal<detail::posix_charset_placeholder>::type const space = {{"space", false}};
|
Chris@16
|
351
|
Chris@16
|
352 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
353 /// \brief Matches an upper-case character.
|
Chris@16
|
354 ///
|
Chris@16
|
355 /// The regex traits are used to determine which characters are upper-case.
|
Chris@16
|
356 /// To match any character that is not upper-case, use ~upper.
|
Chris@16
|
357 ///
|
Chris@16
|
358 /// \attention upper is equivalent to /[[:upper:]]/ in perl. ~upper is equivalent
|
Chris@16
|
359 /// to /[[:^upper:]]/ in perl.
|
Chris@16
|
360 proto::terminal<detail::posix_charset_placeholder>::type const upper = {{"upper", false}};
|
Chris@16
|
361
|
Chris@16
|
362 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
363 /// \brief Matches a hexadecimal digit character.
|
Chris@16
|
364 ///
|
Chris@16
|
365 /// The regex traits are used to determine which characters are hex digits.
|
Chris@16
|
366 /// To match any character that is not a hex digit, use ~xdigit.
|
Chris@16
|
367 ///
|
Chris@16
|
368 /// \attention xdigit is equivalent to /[[:xdigit:]]/ in perl. ~xdigit is equivalent
|
Chris@16
|
369 /// to /[[:^xdigit:]]/ in perl.
|
Chris@16
|
370 proto::terminal<detail::posix_charset_placeholder>::type const xdigit = {{"xdigit", false}};
|
Chris@16
|
371
|
Chris@16
|
372 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
373 /// \brief Beginning of sequence assertion.
|
Chris@16
|
374 ///
|
Chris@16
|
375 /// For the character sequence [begin, end), 'bos' matches the
|
Chris@16
|
376 /// zero-width sub-sequence [begin, begin).
|
Chris@16
|
377 proto::terminal<detail::assert_bos_matcher>::type const bos = {{}};
|
Chris@16
|
378
|
Chris@16
|
379 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
380 /// \brief End of sequence assertion.
|
Chris@16
|
381 ///
|
Chris@16
|
382 /// For the character sequence [begin, end),
|
Chris@16
|
383 /// 'eos' matches the zero-width sub-sequence [end, end).
|
Chris@16
|
384 ///
|
Chris@16
|
385 /// \attention Unlike the perl end of sequence assertion \$, 'eos' will
|
Chris@16
|
386 /// not match at the position [end-1, end-1) if *(end-1) is '\\n'. To
|
Chris@16
|
387 /// get that behavior, use (!_n >> eos).
|
Chris@16
|
388 proto::terminal<detail::assert_eos_matcher>::type const eos = {{}};
|
Chris@16
|
389
|
Chris@16
|
390 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
391 /// \brief Beginning of line assertion.
|
Chris@16
|
392 ///
|
Chris@16
|
393 /// 'bol' matches the zero-width sub-sequence
|
Chris@16
|
394 /// immediately following a logical newline sequence. The regex traits
|
Chris@16
|
395 /// is used to determine what constitutes a logical newline sequence.
|
Chris@16
|
396 proto::terminal<detail::assert_bol_placeholder>::type const bol = {{}};
|
Chris@16
|
397
|
Chris@16
|
398 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
399 /// \brief End of line assertion.
|
Chris@16
|
400 ///
|
Chris@16
|
401 /// 'eol' matches the zero-width sub-sequence
|
Chris@16
|
402 /// immediately preceeding a logical newline sequence. The regex traits
|
Chris@16
|
403 /// is used to determine what constitutes a logical newline sequence.
|
Chris@16
|
404 proto::terminal<detail::assert_eol_placeholder>::type const eol = {{}};
|
Chris@16
|
405
|
Chris@16
|
406 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
407 /// \brief Beginning of word assertion.
|
Chris@16
|
408 ///
|
Chris@16
|
409 /// 'bow' matches the zero-width sub-sequence
|
Chris@16
|
410 /// immediately following a non-word character and preceeding a word character.
|
Chris@16
|
411 /// The regex traits are used to determine what constitutes a word character.
|
Chris@16
|
412 proto::terminal<detail::assert_word_begin>::type const bow = {{}};
|
Chris@16
|
413
|
Chris@16
|
414 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
415 /// \brief End of word assertion.
|
Chris@16
|
416 ///
|
Chris@16
|
417 /// 'eow' matches the zero-width sub-sequence
|
Chris@16
|
418 /// immediately following a word character and preceeding a non-word character.
|
Chris@16
|
419 /// The regex traits are used to determine what constitutes a word character.
|
Chris@16
|
420 proto::terminal<detail::assert_word_end>::type const eow = {{}};
|
Chris@16
|
421
|
Chris@16
|
422 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
423 /// \brief Word boundary assertion.
|
Chris@16
|
424 ///
|
Chris@16
|
425 /// '_b' matches the zero-width sub-sequence at the beginning or the end of a word.
|
Chris@16
|
426 /// It is equivalent to (bow | eow). The regex traits are used to determine what
|
Chris@16
|
427 /// constitutes a word character. To match a non-word boundary, use ~_b.
|
Chris@16
|
428 ///
|
Chris@16
|
429 /// \attention _b is like \\b in perl. ~_b is like \\B in perl.
|
Chris@16
|
430 proto::terminal<detail::assert_word_boundary>::type const _b = {{}};
|
Chris@16
|
431
|
Chris@16
|
432 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
433 /// \brief Matches a word character.
|
Chris@16
|
434 ///
|
Chris@16
|
435 /// '_w' matches a single word character. The regex traits are used to determine which
|
Chris@16
|
436 /// characters are word characters. Use ~_w to match a character that is not a word
|
Chris@16
|
437 /// character.
|
Chris@16
|
438 ///
|
Chris@16
|
439 /// \attention _w is like \\w in perl. ~_w is like \\W in perl.
|
Chris@16
|
440 proto::terminal<detail::posix_charset_placeholder>::type const _w = {{"w", false}};
|
Chris@16
|
441
|
Chris@16
|
442 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
443 /// \brief Matches a digit character.
|
Chris@16
|
444 ///
|
Chris@16
|
445 /// '_d' matches a single digit character. The regex traits are used to determine which
|
Chris@16
|
446 /// characters are digits. Use ~_d to match a character that is not a digit
|
Chris@16
|
447 /// character.
|
Chris@16
|
448 ///
|
Chris@16
|
449 /// \attention _d is like \\d in perl. ~_d is like \\D in perl.
|
Chris@16
|
450 proto::terminal<detail::posix_charset_placeholder>::type const _d = {{"d", false}};
|
Chris@16
|
451
|
Chris@16
|
452 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
453 /// \brief Matches a space character.
|
Chris@16
|
454 ///
|
Chris@16
|
455 /// '_s' matches a single space character. The regex traits are used to determine which
|
Chris@16
|
456 /// characters are space characters. Use ~_s to match a character that is not a space
|
Chris@16
|
457 /// character.
|
Chris@16
|
458 ///
|
Chris@16
|
459 /// \attention _s is like \\s in perl. ~_s is like \\S in perl.
|
Chris@16
|
460 proto::terminal<detail::posix_charset_placeholder>::type const _s = {{"s", false}};
|
Chris@16
|
461
|
Chris@16
|
462 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
463 /// \brief Matches a literal newline character, '\\n'.
|
Chris@16
|
464 ///
|
Chris@16
|
465 /// '_n' matches a single newline character, '\\n'. Use ~_n to match a character
|
Chris@16
|
466 /// that is not a newline.
|
Chris@16
|
467 ///
|
Chris@16
|
468 /// \attention ~_n is like '.' in perl without the /s modifier.
|
Chris@16
|
469 proto::terminal<char>::type const _n = {'\n'};
|
Chris@16
|
470
|
Chris@16
|
471 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
472 /// \brief Matches a logical newline sequence.
|
Chris@16
|
473 ///
|
Chris@16
|
474 /// '_ln' matches a logical newline sequence. This can be any character in the
|
Chris@16
|
475 /// line separator class, as determined by the regex traits, or the '\\r\\n' sequence.
|
Chris@16
|
476 /// For the purpose of back-tracking, '\\r\\n' is treated as a unit.
|
Chris@16
|
477 /// To match any one character that is not a logical newline, use ~_ln.
|
Chris@16
|
478 detail::logical_newline_xpression const _ln = {{}};
|
Chris@16
|
479
|
Chris@16
|
480 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
481 /// \brief Matches any one character.
|
Chris@16
|
482 ///
|
Chris@16
|
483 /// Match any character, similar to '.' in perl syntax with the /s modifier.
|
Chris@16
|
484 /// '_' matches any one character, including the newline.
|
Chris@16
|
485 ///
|
Chris@16
|
486 /// \attention To match any character except the newline, use ~_n
|
Chris@16
|
487 proto::terminal<detail::any_matcher>::type const _ = {{}};
|
Chris@16
|
488
|
Chris@16
|
489 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
490 /// \brief Reference to the current regex object
|
Chris@16
|
491 ///
|
Chris@16
|
492 /// Useful when constructing recursive regular expression objects. The 'self'
|
Chris@16
|
493 /// identifier is a short-hand for the current regex object. For instance,
|
Chris@16
|
494 /// sregex rx = '(' >> (self | nil) >> ')'; will create a regex object that
|
Chris@16
|
495 /// matches balanced parens such as "((()))".
|
Chris@16
|
496 proto::terminal<detail::self_placeholder>::type const self = {{}};
|
Chris@16
|
497
|
Chris@16
|
498 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
499 /// \brief Used to create character sets.
|
Chris@16
|
500 ///
|
Chris@16
|
501 /// There are two ways to create character sets with the 'set' identifier. The
|
Chris@16
|
502 /// easiest is to create a comma-separated list of the characters in the set,
|
Chris@16
|
503 /// as in (set= 'a','b','c'). This set will match 'a', 'b', or 'c'. The other
|
Chris@16
|
504 /// way is to define the set as an argument to the set subscript operator.
|
Chris@16
|
505 /// For instance, set[ 'a' | range('b','c') | digit ] will match an 'a', 'b',
|
Chris@16
|
506 /// 'c' or a digit character.
|
Chris@16
|
507 ///
|
Chris@16
|
508 /// To complement a set, apply the '~' operator. For instance, ~(set= 'a','b','c')
|
Chris@16
|
509 /// will match any character that is not an 'a', 'b', or 'c'.
|
Chris@16
|
510 ///
|
Chris@16
|
511 /// Sets can be composed of other, possibly complemented, sets. For instance,
|
Chris@16
|
512 /// set[ ~digit | ~(set= 'a','b','c') ].
|
Chris@16
|
513 detail::set_initializer_type const set = {{}};
|
Chris@16
|
514
|
Chris@16
|
515 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
516 /// \brief Sub-match placeholder type, used to create named captures in
|
Chris@16
|
517 /// static regexes.
|
Chris@16
|
518 ///
|
Chris@16
|
519 /// \c mark_tag is the type of the global sub-match placeholders \c s0, \c s1, etc.. You
|
Chris@16
|
520 /// can use the \c mark_tag type to create your own sub-match placeholders with
|
Chris@16
|
521 /// more meaningful names. This is roughly equivalent to the "named capture"
|
Chris@16
|
522 /// feature of dynamic regular expressions.
|
Chris@16
|
523 ///
|
Chris@16
|
524 /// To create a named sub-match placeholder, initialize it with a unique integer.
|
Chris@16
|
525 /// The integer must only be unique within the regex in which the placeholder
|
Chris@16
|
526 /// is used. Then you can use it within static regexes to created sub-matches
|
Chris@16
|
527 /// by assigning a sub-expression to it, or to refer back to already created
|
Chris@16
|
528 /// sub-matches.
|
Chris@16
|
529 ///
|
Chris@16
|
530 /// \code
|
Chris@16
|
531 /// mark_tag number(1); // "number" is now equivalent to "s1"
|
Chris@16
|
532 /// // Match a number, followed by a space and the same number again
|
Chris@16
|
533 /// sregex rx = (number = +_d) >> ' ' >> number;
|
Chris@16
|
534 /// \endcode
|
Chris@16
|
535 ///
|
Chris@16
|
536 /// After a successful \c regex_match() or \c regex_search(), the sub-match placeholder
|
Chris@16
|
537 /// can be used to index into the <tt>match_results\<\></tt> object to retrieve the
|
Chris@16
|
538 /// corresponding sub-match.
|
Chris@16
|
539 struct mark_tag
|
Chris@16
|
540 : proto::extends<detail::basic_mark_tag, mark_tag, detail::regex_domain>
|
Chris@16
|
541 {
|
Chris@16
|
542 private:
|
Chris@16
|
543 typedef proto::extends<detail::basic_mark_tag, mark_tag, detail::regex_domain> base_type;
|
Chris@16
|
544
|
Chris@16
|
545 static detail::basic_mark_tag make_tag(int mark_nbr)
|
Chris@16
|
546 {
|
Chris@16
|
547 detail::basic_mark_tag mark = {{mark_nbr}};
|
Chris@16
|
548 return mark;
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 public:
|
Chris@16
|
552 /// \brief Initialize a mark_tag placeholder
|
Chris@16
|
553 /// \param mark_nbr An integer that uniquely identifies this \c mark_tag
|
Chris@16
|
554 /// within the static regexes in which this \c mark_tag will be used.
|
Chris@16
|
555 /// \pre <tt>mark_nbr \> 0</tt>
|
Chris@16
|
556 mark_tag(int mark_nbr)
|
Chris@16
|
557 : base_type(mark_tag::make_tag(mark_nbr))
|
Chris@16
|
558 {
|
Chris@16
|
559 // Marks numbers must be integers greater than 0.
|
Chris@16
|
560 BOOST_ASSERT(mark_nbr > 0);
|
Chris@16
|
561 }
|
Chris@16
|
562
|
Chris@16
|
563 /// INTERNAL ONLY
|
Chris@16
|
564 operator detail::basic_mark_tag const &() const
|
Chris@16
|
565 {
|
Chris@16
|
566 return this->proto_base();
|
Chris@16
|
567 }
|
Chris@16
|
568
|
Chris@16
|
569 BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT(mark_tag)
|
Chris@16
|
570 };
|
Chris@16
|
571
|
Chris@16
|
572 // This macro is used when declaring mark_tags that are global because
|
Chris@16
|
573 // it guarantees that they are statically initialized. That avoids
|
Chris@16
|
574 // order-of-initialization bugs. In user code, the simpler: mark_tag s0(0);
|
Chris@16
|
575 // would be preferable.
|
Chris@16
|
576 /// INTERNAL ONLY
|
Chris@16
|
577 #define BOOST_XPRESSIVE_GLOBAL_MARK_TAG(NAME, VALUE) \
|
Chris@16
|
578 boost::xpressive::mark_tag::proto_base_expr const NAME = {{VALUE}} \
|
Chris@16
|
579 /**/
|
Chris@16
|
580
|
Chris@16
|
581 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
582 /// \brief Sub-match placeholder, like $& in Perl
|
Chris@16
|
583 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s0, 0);
|
Chris@16
|
584
|
Chris@16
|
585 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
586 /// \brief Sub-match placeholder, like $1 in perl.
|
Chris@16
|
587 ///
|
Chris@16
|
588 /// To create a sub-match, assign a sub-expression to the sub-match placeholder.
|
Chris@16
|
589 /// For instance, (s1= _) will match any one character and remember which
|
Chris@16
|
590 /// character was matched in the 1st sub-match. Later in the pattern, you can
|
Chris@16
|
591 /// refer back to the sub-match. For instance, (s1= _) >> s1 will match any
|
Chris@16
|
592 /// character, and then match the same character again.
|
Chris@16
|
593 ///
|
Chris@16
|
594 /// After a successful regex_match() or regex_search(), the sub-match placeholders
|
Chris@16
|
595 /// can be used to index into the match_results\<\> object to retrieve the Nth
|
Chris@16
|
596 /// sub-match.
|
Chris@16
|
597 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s1, 1);
|
Chris@16
|
598 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s2, 2);
|
Chris@16
|
599 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s3, 3);
|
Chris@16
|
600 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s4, 4);
|
Chris@16
|
601 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s5, 5);
|
Chris@16
|
602 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s6, 6);
|
Chris@16
|
603 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s7, 7);
|
Chris@16
|
604 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s8, 8);
|
Chris@16
|
605 BOOST_XPRESSIVE_GLOBAL_MARK_TAG(s9, 9);
|
Chris@16
|
606
|
Chris@16
|
607 // NOTE: For the purpose of xpressive's documentation, make icase() look like an
|
Chris@16
|
608 // ordinary function. In reality, it is a function object defined in detail/icase.hpp
|
Chris@16
|
609 // so that it can serve double-duty as regex_constants::icase, the syntax_option_type.
|
Chris@16
|
610 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
|
Chris@16
|
611 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
612 /// \brief Makes a sub-expression case-insensitive.
|
Chris@16
|
613 ///
|
Chris@16
|
614 /// Use icase() to make a sub-expression case-insensitive. For instance,
|
Chris@16
|
615 /// "foo" >> icase(set['b'] >> "ar") will match "foo" exactly followed by
|
Chris@16
|
616 /// "bar" irrespective of case.
|
Chris@16
|
617 template<typename Expr> detail::unspecified icase(Expr const &expr) { return 0; }
|
Chris@16
|
618 #endif
|
Chris@16
|
619
|
Chris@16
|
620 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
621 /// \brief Makes a literal into a regular expression.
|
Chris@16
|
622 ///
|
Chris@16
|
623 /// Use as_xpr() to turn a literal into a regular expression. For instance,
|
Chris@16
|
624 /// "foo" >> "bar" will not compile because both operands to the right-shift
|
Chris@16
|
625 /// operator are const char*, and no such operator exists. Use as_xpr("foo") >> "bar"
|
Chris@16
|
626 /// instead.
|
Chris@16
|
627 ///
|
Chris@16
|
628 /// You can use as_xpr() with character literals in addition to string literals.
|
Chris@16
|
629 /// For instance, as_xpr('a') will match an 'a'. You can also complement a
|
Chris@16
|
630 /// character literal, as with ~as_xpr('a'). This will match any one character
|
Chris@16
|
631 /// that is not an 'a'.
|
Chris@16
|
632 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
|
Chris@16
|
633 template<typename Literal> detail::unspecified as_xpr(Literal const &literal) { return 0; }
|
Chris@16
|
634 #else
|
Chris@16
|
635 proto::functional::as_expr<> const as_xpr = {};
|
Chris@16
|
636 #endif
|
Chris@16
|
637
|
Chris@16
|
638 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
639 /// \brief Embed a regex object by reference.
|
Chris@16
|
640 ///
|
Chris@16
|
641 /// \param rex The basic_regex object to embed by reference.
|
Chris@16
|
642 template<typename BidiIter>
|
Chris@16
|
643 inline typename proto::terminal<reference_wrapper<basic_regex<BidiIter> const> >::type const
|
Chris@16
|
644 by_ref(basic_regex<BidiIter> const &rex)
|
Chris@16
|
645 {
|
Chris@16
|
646 reference_wrapper<basic_regex<BidiIter> const> ref(rex);
|
Chris@16
|
647 return proto::terminal<reference_wrapper<basic_regex<BidiIter> const> >::type::make(ref);
|
Chris@16
|
648 }
|
Chris@16
|
649
|
Chris@16
|
650 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
651 /// \brief Match a range of characters.
|
Chris@16
|
652 ///
|
Chris@16
|
653 /// Match any character in the range [ch_min, ch_max].
|
Chris@16
|
654 ///
|
Chris@16
|
655 /// \param ch_min The lower end of the range to match.
|
Chris@16
|
656 /// \param ch_max The upper end of the range to match.
|
Chris@16
|
657 template<typename Char>
|
Chris@16
|
658 inline typename proto::terminal<detail::range_placeholder<Char> >::type const
|
Chris@16
|
659 range(Char ch_min, Char ch_max)
|
Chris@16
|
660 {
|
Chris@16
|
661 detail::range_placeholder<Char> that = {ch_min, ch_max, false};
|
Chris@16
|
662 return proto::terminal<detail::range_placeholder<Char> >::type::make(that);
|
Chris@16
|
663 }
|
Chris@16
|
664
|
Chris@16
|
665 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
666 /// \brief Make a sub-expression optional. Equivalent to !as_xpr(expr).
|
Chris@16
|
667 ///
|
Chris@16
|
668 /// \param expr The sub-expression to make optional.
|
Chris@16
|
669 template<typename Expr>
|
Chris@16
|
670 typename proto::result_of::make_expr<
|
Chris@16
|
671 proto::tag::logical_not
|
Chris@16
|
672 , proto::default_domain
|
Chris@16
|
673 , Expr const &
|
Chris@16
|
674 >::type const
|
Chris@16
|
675 optional(Expr const &expr)
|
Chris@16
|
676 {
|
Chris@16
|
677 return proto::make_expr<
|
Chris@16
|
678 proto::tag::logical_not
|
Chris@16
|
679 , proto::default_domain
|
Chris@16
|
680 >(boost::ref(expr));
|
Chris@16
|
681 }
|
Chris@16
|
682
|
Chris@16
|
683 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
684 /// \brief Repeat a sub-expression multiple times.
|
Chris@16
|
685 ///
|
Chris@16
|
686 /// There are two forms of the repeat\<\>() function template. To match a
|
Chris@16
|
687 /// sub-expression N times, use repeat\<N\>(expr). To match a sub-expression
|
Chris@16
|
688 /// from M to N times, use repeat\<M,N\>(expr).
|
Chris@16
|
689 ///
|
Chris@16
|
690 /// The repeat\<\>() function creates a greedy quantifier. To make the quantifier
|
Chris@16
|
691 /// non-greedy, apply the unary minus operator, as in -repeat\<M,N\>(expr).
|
Chris@16
|
692 ///
|
Chris@16
|
693 /// \param expr The sub-expression to repeat.
|
Chris@16
|
694 template<unsigned int Min, unsigned int Max, typename Expr>
|
Chris@16
|
695 typename proto::result_of::make_expr<
|
Chris@16
|
696 detail::generic_quant_tag<Min, Max>
|
Chris@16
|
697 , proto::default_domain
|
Chris@16
|
698 , Expr const &
|
Chris@16
|
699 >::type const
|
Chris@16
|
700 repeat(Expr const &expr)
|
Chris@16
|
701 {
|
Chris@16
|
702 return proto::make_expr<
|
Chris@16
|
703 detail::generic_quant_tag<Min, Max>
|
Chris@16
|
704 , proto::default_domain
|
Chris@16
|
705 >(boost::ref(expr));
|
Chris@16
|
706 }
|
Chris@16
|
707
|
Chris@16
|
708 /// \overload
|
Chris@16
|
709 ///
|
Chris@16
|
710 template<unsigned int Count, typename Expr2>
|
Chris@16
|
711 typename proto::result_of::make_expr<
|
Chris@16
|
712 detail::generic_quant_tag<Count, Count>
|
Chris@16
|
713 , proto::default_domain
|
Chris@16
|
714 , Expr2 const &
|
Chris@16
|
715 >::type const
|
Chris@16
|
716 repeat(Expr2 const &expr2)
|
Chris@16
|
717 {
|
Chris@16
|
718 return proto::make_expr<
|
Chris@16
|
719 detail::generic_quant_tag<Count, Count>
|
Chris@16
|
720 , proto::default_domain
|
Chris@16
|
721 >(boost::ref(expr2));
|
Chris@16
|
722 }
|
Chris@16
|
723
|
Chris@16
|
724 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
725 /// \brief Create an independent sub-expression.
|
Chris@16
|
726 ///
|
Chris@16
|
727 /// Turn off back-tracking for a sub-expression. Any branches or repeats within
|
Chris@16
|
728 /// the sub-expression will match only one way, and no other alternatives are
|
Chris@16
|
729 /// tried.
|
Chris@16
|
730 ///
|
Chris@16
|
731 /// \attention keep(expr) is equivalent to the perl (?>...) extension.
|
Chris@16
|
732 ///
|
Chris@16
|
733 /// \param expr The sub-expression to modify.
|
Chris@16
|
734 template<typename Expr>
|
Chris@16
|
735 typename proto::result_of::make_expr<
|
Chris@16
|
736 detail::keeper_tag
|
Chris@16
|
737 , proto::default_domain
|
Chris@16
|
738 , Expr const &
|
Chris@16
|
739 >::type const
|
Chris@16
|
740 keep(Expr const &expr)
|
Chris@16
|
741 {
|
Chris@16
|
742 return proto::make_expr<
|
Chris@16
|
743 detail::keeper_tag
|
Chris@16
|
744 , proto::default_domain
|
Chris@16
|
745 >(boost::ref(expr));
|
Chris@16
|
746 }
|
Chris@16
|
747
|
Chris@16
|
748 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
749 /// \brief Look-ahead assertion.
|
Chris@16
|
750 ///
|
Chris@16
|
751 /// before(expr) succeeds if the expr sub-expression would match at the current
|
Chris@16
|
752 /// position in the sequence, but expr is not included in the match. For instance,
|
Chris@16
|
753 /// before("foo") succeeds if we are before a "foo". Look-ahead assertions can be
|
Chris@16
|
754 /// negated with the bit-compliment operator.
|
Chris@16
|
755 ///
|
Chris@16
|
756 /// \attention before(expr) is equivalent to the perl (?=...) extension.
|
Chris@16
|
757 /// ~before(expr) is a negative look-ahead assertion, equivalent to the
|
Chris@16
|
758 /// perl (?!...) extension.
|
Chris@16
|
759 ///
|
Chris@16
|
760 /// \param expr The sub-expression to put in the look-ahead assertion.
|
Chris@16
|
761 template<typename Expr>
|
Chris@16
|
762 typename proto::result_of::make_expr<
|
Chris@16
|
763 detail::lookahead_tag
|
Chris@16
|
764 , proto::default_domain
|
Chris@16
|
765 , Expr const &
|
Chris@16
|
766 >::type const
|
Chris@16
|
767 before(Expr const &expr)
|
Chris@16
|
768 {
|
Chris@16
|
769 return proto::make_expr<
|
Chris@16
|
770 detail::lookahead_tag
|
Chris@16
|
771 , proto::default_domain
|
Chris@16
|
772 >(boost::ref(expr));
|
Chris@16
|
773 }
|
Chris@16
|
774
|
Chris@16
|
775 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
776 /// \brief Look-behind assertion.
|
Chris@16
|
777 ///
|
Chris@16
|
778 /// after(expr) succeeds if the expr sub-expression would match at the current
|
Chris@16
|
779 /// position minus N in the sequence, where N is the width of expr. expr is not included in
|
Chris@16
|
780 /// the match. For instance, after("foo") succeeds if we are after a "foo". Look-behind
|
Chris@16
|
781 /// assertions can be negated with the bit-complement operator.
|
Chris@16
|
782 ///
|
Chris@16
|
783 /// \attention after(expr) is equivalent to the perl (?<=...) extension.
|
Chris@16
|
784 /// ~after(expr) is a negative look-behind assertion, equivalent to the
|
Chris@16
|
785 /// perl (?<!...) extension.
|
Chris@16
|
786 ///
|
Chris@16
|
787 /// \param expr The sub-expression to put in the look-ahead assertion.
|
Chris@16
|
788 ///
|
Chris@16
|
789 /// \pre expr cannot match a variable number of characters.
|
Chris@16
|
790 template<typename Expr>
|
Chris@16
|
791 typename proto::result_of::make_expr<
|
Chris@16
|
792 detail::lookbehind_tag
|
Chris@16
|
793 , proto::default_domain
|
Chris@16
|
794 , Expr const &
|
Chris@16
|
795 >::type const
|
Chris@16
|
796 after(Expr const &expr)
|
Chris@16
|
797 {
|
Chris@16
|
798 return proto::make_expr<
|
Chris@16
|
799 detail::lookbehind_tag
|
Chris@16
|
800 , proto::default_domain
|
Chris@16
|
801 >(boost::ref(expr));
|
Chris@16
|
802 }
|
Chris@16
|
803
|
Chris@16
|
804 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
805 /// \brief Specify a regex traits or a std::locale.
|
Chris@16
|
806 ///
|
Chris@16
|
807 /// imbue() instructs the regex engine to use the specified traits or locale
|
Chris@16
|
808 /// when matching the regex. The entire expression must use the same traits/locale.
|
Chris@16
|
809 /// For instance, the following specifies a locale for use with a regex:
|
Chris@16
|
810 /// std::locale loc;
|
Chris@16
|
811 /// sregex rx = imbue(loc)(+digit);
|
Chris@16
|
812 ///
|
Chris@16
|
813 /// \param loc The std::locale or regex traits object.
|
Chris@16
|
814 template<typename Locale>
|
Chris@16
|
815 inline detail::modifier_op<detail::locale_modifier<Locale> > const
|
Chris@16
|
816 imbue(Locale const &loc)
|
Chris@16
|
817 {
|
Chris@16
|
818 detail::modifier_op<detail::locale_modifier<Locale> > mod =
|
Chris@16
|
819 {
|
Chris@16
|
820 detail::locale_modifier<Locale>(loc)
|
Chris@16
|
821 , regex_constants::ECMAScript
|
Chris@16
|
822 };
|
Chris@16
|
823 return mod;
|
Chris@16
|
824 }
|
Chris@16
|
825
|
Chris@16
|
826 proto::terminal<detail::attribute_placeholder<mpl::int_<1> > >::type const a1 = {{}};
|
Chris@16
|
827 proto::terminal<detail::attribute_placeholder<mpl::int_<2> > >::type const a2 = {{}};
|
Chris@16
|
828 proto::terminal<detail::attribute_placeholder<mpl::int_<3> > >::type const a3 = {{}};
|
Chris@16
|
829 proto::terminal<detail::attribute_placeholder<mpl::int_<4> > >::type const a4 = {{}};
|
Chris@16
|
830 proto::terminal<detail::attribute_placeholder<mpl::int_<5> > >::type const a5 = {{}};
|
Chris@16
|
831 proto::terminal<detail::attribute_placeholder<mpl::int_<6> > >::type const a6 = {{}};
|
Chris@16
|
832 proto::terminal<detail::attribute_placeholder<mpl::int_<7> > >::type const a7 = {{}};
|
Chris@16
|
833 proto::terminal<detail::attribute_placeholder<mpl::int_<8> > >::type const a8 = {{}};
|
Chris@16
|
834 proto::terminal<detail::attribute_placeholder<mpl::int_<9> > >::type const a9 = {{}};
|
Chris@16
|
835
|
Chris@16
|
836 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
837 /// \brief Specify which characters to skip when matching a regex.
|
Chris@16
|
838 ///
|
Chris@16
|
839 /// <tt>skip()</tt> instructs the regex engine to skip certain characters when matching
|
Chris@16
|
840 /// a regex. It is most useful for writing regexes that ignore whitespace.
|
Chris@16
|
841 /// For instance, the following specifies a regex that skips whitespace and
|
Chris@16
|
842 /// punctuation:
|
Chris@16
|
843 ///
|
Chris@16
|
844 /// \code
|
Chris@16
|
845 /// // A sentence is one or more words separated by whitespace
|
Chris@16
|
846 /// // and punctuation.
|
Chris@16
|
847 /// sregex word = +alpha;
|
Chris@16
|
848 /// sregex sentence = skip(set[_s | punct])( +word );
|
Chris@16
|
849 /// \endcode
|
Chris@16
|
850 ///
|
Chris@16
|
851 /// The way it works in the above example is to insert
|
Chris@16
|
852 /// <tt>keep(*set[_s | punct])</tt> before each primitive within the regex.
|
Chris@16
|
853 /// A "primitive" includes terminals like strings, character sets and nested
|
Chris@16
|
854 /// regexes. A final <tt>*set[_s | punct]</tt> is added to the end of the
|
Chris@16
|
855 /// regex. The regex <tt>sentence</tt> specified above is equivalent to
|
Chris@16
|
856 /// the following:
|
Chris@16
|
857 ///
|
Chris@16
|
858 /// \code
|
Chris@16
|
859 /// sregex sentence = +( keep(*set[_s | punct]) >> word )
|
Chris@16
|
860 /// >> *set[_s | punct];
|
Chris@16
|
861 /// \endcode
|
Chris@16
|
862 ///
|
Chris@16
|
863 /// \attention Skipping does not affect how nested regexes are handled because
|
Chris@16
|
864 /// they are treated atomically. String literals are also treated
|
Chris@16
|
865 /// atomically; that is, no skipping is done within a string literal. So
|
Chris@16
|
866 /// <tt>skip(_s)("this that")</tt> is not the same as
|
Chris@16
|
867 /// <tt>skip(_s)("this" >> as_xpr("that"))</tt>. The first will only match
|
Chris@16
|
868 /// when there is only one space between "this" and "that". The second will
|
Chris@16
|
869 /// skip any and all whitespace between "this" and "that".
|
Chris@16
|
870 ///
|
Chris@16
|
871 /// \param skip A regex that specifies which characters to skip.
|
Chris@16
|
872 template<typename Skip>
|
Chris@16
|
873 detail::skip_directive<Skip> skip(Skip const &skip)
|
Chris@16
|
874 {
|
Chris@16
|
875 return detail::skip_directive<Skip>(skip);
|
Chris@16
|
876 }
|
Chris@16
|
877
|
Chris@16
|
878 namespace detail
|
Chris@16
|
879 {
|
Chris@16
|
880 inline void ignore_unused_regex_primitives()
|
Chris@16
|
881 {
|
Chris@16
|
882 detail::ignore_unused(repeat_max);
|
Chris@16
|
883 detail::ignore_unused(inf);
|
Chris@16
|
884 detail::ignore_unused(epsilon);
|
Chris@16
|
885 detail::ignore_unused(nil);
|
Chris@16
|
886 detail::ignore_unused(alnum);
|
Chris@16
|
887 detail::ignore_unused(bos);
|
Chris@16
|
888 detail::ignore_unused(eos);
|
Chris@16
|
889 detail::ignore_unused(bol);
|
Chris@16
|
890 detail::ignore_unused(eol);
|
Chris@16
|
891 detail::ignore_unused(bow);
|
Chris@16
|
892 detail::ignore_unused(eow);
|
Chris@16
|
893 detail::ignore_unused(_b);
|
Chris@16
|
894 detail::ignore_unused(_w);
|
Chris@16
|
895 detail::ignore_unused(_d);
|
Chris@16
|
896 detail::ignore_unused(_s);
|
Chris@16
|
897 detail::ignore_unused(_n);
|
Chris@16
|
898 detail::ignore_unused(_ln);
|
Chris@16
|
899 detail::ignore_unused(_);
|
Chris@16
|
900 detail::ignore_unused(self);
|
Chris@16
|
901 detail::ignore_unused(set);
|
Chris@16
|
902 detail::ignore_unused(s0);
|
Chris@16
|
903 detail::ignore_unused(s1);
|
Chris@16
|
904 detail::ignore_unused(s2);
|
Chris@16
|
905 detail::ignore_unused(s3);
|
Chris@16
|
906 detail::ignore_unused(s4);
|
Chris@16
|
907 detail::ignore_unused(s5);
|
Chris@16
|
908 detail::ignore_unused(s6);
|
Chris@16
|
909 detail::ignore_unused(s7);
|
Chris@16
|
910 detail::ignore_unused(s8);
|
Chris@16
|
911 detail::ignore_unused(s9);
|
Chris@16
|
912 detail::ignore_unused(a1);
|
Chris@16
|
913 detail::ignore_unused(a2);
|
Chris@16
|
914 detail::ignore_unused(a3);
|
Chris@16
|
915 detail::ignore_unused(a4);
|
Chris@16
|
916 detail::ignore_unused(a5);
|
Chris@16
|
917 detail::ignore_unused(a6);
|
Chris@16
|
918 detail::ignore_unused(a7);
|
Chris@16
|
919 detail::ignore_unused(a8);
|
Chris@16
|
920 detail::ignore_unused(a9);
|
Chris@16
|
921 detail::ignore_unused(as_xpr);
|
Chris@16
|
922 }
|
Chris@16
|
923 }
|
Chris@16
|
924
|
Chris@16
|
925 }} // namespace boost::xpressive
|
Chris@16
|
926
|
Chris@16
|
927 #endif
|