Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/xpressive/detail/dynamic/parser.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 9.7 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2/// \file parser.hpp
3/// Contains the definition of regex_compiler, a factory for building regex objects
4/// from strings.
5//
6//  Copyright 2004 Eric Niebler. Distributed under the Boost
7//  Software License, Version 1.0. (See accompanying file
8//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10#ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
11#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
12
13// MS compatible compilers support #pragma once
14#if defined(_MSC_VER) && (_MSC_VER >= 1020)
15# pragma once
16# pragma warning(push)
17# pragma warning(disable : 4127) // conditional expression is constant
18#endif
19
20#include <boost/assert.hpp>
21#include <boost/xpressive/regex_constants.hpp>
22#include <boost/xpressive/detail/detail_fwd.hpp>
23#include <boost/xpressive/detail/core/matchers.hpp>
24#include <boost/xpressive/detail/dynamic/dynamic.hpp>
25
26// The Regular Expression grammar, in pseudo BNF:
27//
28// expression   = alternates ;
29//
30// alternates   = sequence, *('|', sequence) ;
31//
32// sequence     = quant, *(quant) ;
33//
34// quant        = atom, [*+?] ;
35//
36// atom         = literal             |
37//                '.'                 |
38//                '\' any             |
39//                '(' expression ')' ;
40//
41// literal      = not a meta-character ;
42//
43
44namespace boost { namespace xpressive { namespace detail
45{
46
47///////////////////////////////////////////////////////////////////////////////
48// make_char_xpression
49//
50template<typename BidiIter, typename Char, typename Traits>
51inline sequence<BidiIter> make_char_xpression
52(
53    Char ch
54  , regex_constants::syntax_option_type flags
55  , Traits const &traits
56)
57{
58    if(0 != (regex_constants::icase_ & flags))
59    {
60        literal_matcher<Traits, true, false> matcher(ch, traits);
61        return make_dynamic_xpression<BidiIter>(matcher);
62    }
63    else
64    {
65        literal_matcher<Traits, false, false> matcher(ch, traits);
66        return make_dynamic_xpression<BidiIter>(matcher);
67    }
68}
69
70///////////////////////////////////////////////////////////////////////////////
71// make_any_xpression
72//
73template<typename BidiIter, typename Traits>
74inline sequence<BidiIter> make_any_xpression
75(
76    regex_constants::syntax_option_type flags
77  , Traits const &traits
78)
79{
80    using namespace regex_constants;
81    typedef typename iterator_value<BidiIter>::type char_type;
82    typedef set_matcher<Traits, 2> set_matcher;
83    typedef literal_matcher<Traits, false, true> literal_matcher;
84
85    char_type const newline = traits.widen('\n');
86    set_matcher s(traits);
87    s.set_[0] = newline;
88    s.set_[1] = 0;
89    s.complement();
90
91    switch(((int)not_dot_newline | not_dot_null) & flags)
92    {
93    case not_dot_null:
94        return make_dynamic_xpression<BidiIter>(literal_matcher(char_type(0), traits));
95
96    case not_dot_newline:
97        return make_dynamic_xpression<BidiIter>(literal_matcher(newline, traits));
98
99    case (int)not_dot_newline | not_dot_null:
100        return make_dynamic_xpression<BidiIter>(s);
101
102    default:
103        return make_dynamic_xpression<BidiIter>(any_matcher());
104    }
105}
106
107///////////////////////////////////////////////////////////////////////////////
108// make_literal_xpression
109//
110template<typename BidiIter, typename Char, typename Traits>
111inline sequence<BidiIter> make_literal_xpression
112(
113    std::basic_string<Char> const &literal
114  , regex_constants::syntax_option_type flags
115  , Traits const &traits
116)
117{
118    BOOST_ASSERT(0 != literal.size());
119    if(1 == literal.size())
120    {
121        return make_char_xpression<BidiIter>(literal[0], flags, traits);
122    }
123
124    typedef typename iterator_value<BidiIter>::type char_type;
125    BOOST_MPL_ASSERT((is_same<char_type, Char>));
126
127    if(0 != (regex_constants::icase_ & flags))
128    {
129        string_matcher<Traits, true> matcher(literal, traits);
130        return make_dynamic_xpression<BidiIter>(matcher);
131    }
132    else
133    {
134        string_matcher<Traits, false> matcher(literal, traits);
135        return make_dynamic_xpression<BidiIter>(matcher);
136    }
137}
138
139///////////////////////////////////////////////////////////////////////////////
140// make_backref_xpression
141//
142template<typename BidiIter, typename Traits>
143inline sequence<BidiIter> make_backref_xpression
144(
145    int mark_nbr
146  , regex_constants::syntax_option_type flags
147  , Traits const &traits
148)
149{
150    typedef typename iterator_value<BidiIter>::type char_type;
151    if(0 != (regex_constants::icase_ & flags))
152    {
153        return make_dynamic_xpression<BidiIter>
154        (
155            mark_matcher<Traits, true>(mark_nbr, traits)
156        );
157    }
158    else
159    {
160        return make_dynamic_xpression<BidiIter>
161        (
162            mark_matcher<Traits, false>(mark_nbr, traits)
163        );
164    }
165}
166
167///////////////////////////////////////////////////////////////////////////////
168// merge_charset
169//
170template<typename Char, typename Traits>
171inline void merge_charset
172(
173    basic_chset<Char> &basic
174  , compound_charset<Traits> const &compound
175  , Traits const &traits
176)
177{
178    if(0 != compound.posix_yes())
179    {
180        typename Traits::char_class_type mask = compound.posix_yes();
181        for(int i = 0; i <= UCHAR_MAX; ++i)
182        {
183            if(traits.isctype((Char)i, mask))
184            {
185                basic.set((Char)i);
186            }
187        }
188    }
189
190    if(!compound.posix_no().empty())
191    {
192        for(std::size_t j = 0; j < compound.posix_no().size(); ++j)
193        {
194            typename Traits::char_class_type mask = compound.posix_no()[j];
195            for(int i = 0; i <= UCHAR_MAX; ++i)
196            {
197                if(!traits.isctype((Char)i, mask))
198                {
199                    basic.set((Char)i);
200                }
201            }
202        }
203    }
204
205    if(compound.is_inverted())
206    {
207        basic.inverse();
208    }
209}
210
211///////////////////////////////////////////////////////////////////////////////
212// make_charset_xpression
213//
214template<typename BidiIter, typename Traits>
215inline sequence<BidiIter> make_charset_xpression
216(
217    compound_charset<Traits> &chset
218  , Traits const &traits
219  , regex_constants::syntax_option_type flags
220)
221{
222    typedef typename Traits::char_type char_type;
223    bool const icase = (0 != (regex_constants::icase_ & flags));
224    bool const optimize = 1 == sizeof(char_type) && 0 != (regex_constants::optimize & flags);
225
226    // don't care about compile speed -- fold eveything into a bitset<256>
227    if(optimize)
228    {
229        typedef basic_chset<char_type> charset_type;
230        charset_type charset(chset.basic_chset());
231        if(icase)
232        {
233            charset_matcher<Traits, true, charset_type> matcher(charset);
234            merge_charset(matcher.charset_, chset, traits);
235            return make_dynamic_xpression<BidiIter>(matcher);
236        }
237        else
238        {
239            charset_matcher<Traits, false, charset_type> matcher(charset);
240            merge_charset(matcher.charset_, chset, traits);
241            return make_dynamic_xpression<BidiIter>(matcher);
242        }
243    }
244
245    // special case to make [[:digit:]] fast
246    else if(chset.basic_chset().empty() && chset.posix_no().empty())
247    {
248        BOOST_ASSERT(0 != chset.posix_yes());
249        posix_charset_matcher<Traits> matcher(chset.posix_yes(), chset.is_inverted());
250        return make_dynamic_xpression<BidiIter>(matcher);
251    }
252
253    // default, slow
254    else
255    {
256        if(icase)
257        {
258            charset_matcher<Traits, true> matcher(chset);
259            return make_dynamic_xpression<BidiIter>(matcher);
260        }
261        else
262        {
263            charset_matcher<Traits, false> matcher(chset);
264            return make_dynamic_xpression<BidiIter>(matcher);
265        }
266    }
267}
268
269///////////////////////////////////////////////////////////////////////////////
270// make_posix_charset_xpression
271//
272template<typename BidiIter, typename Traits>
273inline sequence<BidiIter> make_posix_charset_xpression
274(
275    typename Traits::char_class_type m
276  , bool no
277  , regex_constants::syntax_option_type //flags
278  , Traits const & //traits
279)
280{
281    posix_charset_matcher<Traits> charset(m, no);
282    return make_dynamic_xpression<BidiIter>(charset);
283}
284
285///////////////////////////////////////////////////////////////////////////////
286// make_assert_begin_line
287//
288template<typename BidiIter, typename Traits>
289inline sequence<BidiIter> make_assert_begin_line
290(
291    regex_constants::syntax_option_type flags
292  , Traits const &traits
293)
294{
295    if(0 != (regex_constants::single_line & flags))
296    {
297        return detail::make_dynamic_xpression<BidiIter>(detail::assert_bos_matcher());
298    }
299    else
300    {
301        detail::assert_bol_matcher<Traits> matcher(traits);
302        return detail::make_dynamic_xpression<BidiIter>(matcher);
303    }
304}
305
306///////////////////////////////////////////////////////////////////////////////
307// make_assert_end_line
308//
309template<typename BidiIter, typename Traits>
310inline sequence<BidiIter> make_assert_end_line
311(
312    regex_constants::syntax_option_type flags
313  , Traits const &traits
314)
315{
316    if(0 != (regex_constants::single_line & flags))
317    {
318        return detail::make_dynamic_xpression<BidiIter>(detail::assert_eos_matcher());
319    }
320    else
321    {
322        detail::assert_eol_matcher<Traits> matcher(traits);
323        return detail::make_dynamic_xpression<BidiIter>(matcher);
324    }
325}
326
327///////////////////////////////////////////////////////////////////////////////
328// make_assert_word
329//
330template<typename BidiIter, typename Cond, typename Traits>
331inline sequence<BidiIter> make_assert_word(Cond, Traits const &traits)
332{
333    typedef typename iterator_value<BidiIter>::type char_type;
334    return detail::make_dynamic_xpression<BidiIter>
335    (
336        detail::assert_word_matcher<Cond, Traits>(traits)
337    );
338}
339
340}}} // namespace boost::xpressive::detail
341
342#if defined(_MSC_VER) && (_MSC_VER >= 1020)
343# pragma warning(pop)
344#endif
345
346#endif
Note: See TracBrowser for help on using the repository browser.