297fe3f60e9be8daaeb1a5fb20822e000835f8df
[gcc.git] / libstdc++-v3 / include / bits / regex_compiler.h
1 // class template regex -*- C++ -*-
2
3 // Copyright (C) 2010-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /**
26 * @file bits/regex_compiler.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{regex}
29 */
30
31 namespace std _GLIBCXX_VISIBILITY(default)
32 {
33 namespace __detail
34 {
35 _GLIBCXX_BEGIN_NAMESPACE_VERSION
36
37 /**
38 * @addtogroup regex-detail
39 * @{
40 */
41
42 template<typename _CharT, typename _TraitsT>
43 struct _BracketMatcher;
44
45 /// Builds an NFA from an input iterator interval.
46 template<typename _FwdIter, typename _CharT, typename _TraitsT>
47 class _Compiler
48 {
49 public:
50 typedef typename _TraitsT::string_type _StringT;
51 typedef _NFA<_CharT, _TraitsT> _RegexT;
52 typedef regex_constants::syntax_option_type _FlagT;
53
54 _Compiler(_FwdIter __b, _FwdIter __e,
55 const _TraitsT& __traits, _FlagT __flags);
56
57 std::shared_ptr<_RegexT>
58 _M_get_nfa() const
59 { return make_shared<_RegexT>(_M_nfa); }
60
61 private:
62 typedef _Scanner<_FwdIter> _ScannerT;
63 typedef typename _ScannerT::_TokenT _TokenT;
64 typedef _StateSeq<_CharT, _TraitsT> _StateSeqT;
65 typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT;
66 typedef _BracketMatcher<_CharT, _TraitsT> _BMatcherT;
67 typedef std::ctype<_CharT> _CtypeT;
68
69 // accepts a specific token or returns false.
70 bool
71 _M_match_token(_TokenT __token);
72
73 void
74 _M_disjunction();
75
76 void
77 _M_alternative();
78
79 bool
80 _M_term();
81
82 bool
83 _M_assertion();
84
85 void
86 _M_quantifier();
87
88 bool
89 _M_atom();
90
91 bool
92 _M_bracket_expression();
93
94 void
95 _M_expression_term(_BMatcherT& __matcher);
96
97 bool
98 _M_range_expression(_BMatcherT& __matcher);
99
100 bool
101 _M_collating_symbol(_BMatcherT& __matcher);
102
103 bool
104 _M_equivalence_class(_BMatcherT& __matcher);
105
106 bool
107 _M_character_class(_BMatcherT& __matcher);
108
109 int
110 _M_cur_int_value(int __radix);
111
112 bool
113 _M_try_char();
114
115 _StateSeqT
116 _M_pop()
117 {
118 auto ret = _M_stack.top();
119 _M_stack.pop();
120 return ret;
121 }
122
123 _FlagT _M_flags;
124 const _TraitsT& _M_traits;
125 const _CtypeT& _M_ctype;
126 _ScannerT _M_scanner;
127 _RegexT _M_nfa;
128 _StringT _M_value;
129 _StackT _M_stack;
130 };
131
132 template<typename _CharT, typename _TraitsT>
133 struct _AnyMatcher
134 {
135 explicit
136 _AnyMatcher(const _TraitsT& __traits)
137 : _M_traits(__traits)
138 { }
139
140 bool
141 operator()(_CharT __ch) const
142 {
143 return _M_traits.translate(__ch) != '\n'
144 && _M_traits.translate(__ch) != '\r'
145 && _M_traits.translate(__ch) != u'\u2028'
146 && _M_traits.translate(__ch) != u'\u2029';
147 }
148
149 const _TraitsT& _M_traits;
150 };
151
152 template<typename _CharT, typename _TraitsT>
153 struct _CharMatcher
154 {
155 typedef regex_constants::syntax_option_type _FlagT;
156
157 explicit
158 _CharMatcher(_CharT __ch, const _TraitsT& __traits, _FlagT __flags)
159 : _M_ch(_M_translate(__ch)), _M_traits(__traits), _M_flags(__flags)
160 { }
161
162 bool
163 operator()(_CharT __ch) const
164 { return _M_ch == _M_translate(__ch); }
165
166 _CharT
167 _M_translate(_CharT __ch) const
168 {
169 if (_M_flags & regex_constants::icase)
170 return _M_traits.translate_nocase(__ch);
171 else
172 return _M_traits.translate(__ch);
173 }
174
175 const _TraitsT& _M_traits;
176 _FlagT _M_flags;
177 _CharT _M_ch;
178 };
179
180 /// Matches a character range (bracket expression)
181 template<typename _CharT, typename _TraitsT>
182 struct _BracketMatcher
183 {
184 typedef typename _TraitsT::char_class_type _CharClassT;
185 typedef typename _TraitsT::string_type _StringT;
186 typedef regex_constants::syntax_option_type _FlagT;
187
188 explicit
189 _BracketMatcher(bool __is_non_matching,
190 const _TraitsT& __traits,
191 _FlagT __flags)
192 : _M_is_non_matching(__is_non_matching), _M_traits(__traits),
193 _M_flags(__flags), _M_class_set(0)
194 { }
195
196 bool
197 operator()(_CharT) const;
198
199 void
200 _M_add_char(_CharT __c)
201 { _M_char_set.insert(_M_translate(__c)); }
202
203 void
204 _M_add_collating_element(const _StringT& __s)
205 {
206 auto __st = _M_traits.lookup_collatename(__s.data(),
207 __s.data() + __s.size());
208 if (__st.empty())
209 __throw_regex_error(regex_constants::error_collate);
210 _M_char_set.insert(_M_translate(__st[0]));
211 }
212
213 void
214 _M_add_equivalence_class(const _StringT& __s)
215 {
216 auto __st = _M_traits.lookup_collatename(__s.data(),
217 __s.data() + __s.size());
218 if (__st.empty())
219 __throw_regex_error(regex_constants::error_collate);
220 __st = _M_traits.transform_primary(__st.data(),
221 __st.data() + __st.size());
222 _M_equiv_set.insert(__st);
223 }
224
225 void
226 _M_add_character_class(const _StringT& __s)
227 {
228 auto __mask = _M_traits.lookup_classname(__s.data(),
229 __s.data() + __s.size(),
230 _M_is_icase());
231 if (__mask == 0)
232 __throw_regex_error(regex_constants::error_ctype);
233 _M_class_set |= __mask;
234 }
235
236 void
237 _M_make_range(_CharT __l, _CharT __r)
238 {
239 if (_M_flags & regex_constants::collate)
240 _M_range_set.insert(
241 make_pair(_M_get_str(_M_translate(__l)),
242 _M_get_str(_M_translate(__r))));
243 else
244 _M_range_set.insert(make_pair(_M_get_str(__l), _M_get_str(__r)));
245 }
246
247 _CharT
248 _M_translate(_CharT __c) const
249 {
250 if (_M_is_icase())
251 return _M_traits.translate_nocase(__c);
252 else
253 return _M_traits.translate(__c);
254 }
255
256 bool
257 _M_is_icase() const
258 { return _M_flags & regex_constants::icase; }
259
260 _StringT
261 _M_get_str(_CharT __c) const
262 {
263 _StringT __s(1, __c);
264 return _M_traits.transform(__s.begin(), __s.end());
265 }
266
267 std::set<_CharT> _M_char_set;
268 std::set<_StringT> _M_equiv_set;
269 std::set<pair<_StringT, _StringT>> _M_range_set;
270 const _TraitsT& _M_traits;
271 _CharClassT _M_class_set;
272 _FlagT _M_flags;
273 bool _M_is_non_matching;
274 };
275
276 //@} regex-detail
277 _GLIBCXX_END_NAMESPACE_VERSION
278 } // namespace __detail
279 } // namespace std
280
281 #include <bits/regex_compiler.tcc>