49namespace std _GLIBCXX_VISIBILITY(default)
51_GLIBCXX_BEGIN_NAMESPACE_VERSION
55 template<
typename _CharT>
57 _Scanner(
const _CharT* __begin,
const _CharT* __end,
59 : _ScannerBase(__flags),
60 _M_current(__begin), _M_end(__end),
62 _M_eat_escape(_M_is_ecma()
63 ? &_Scanner::_M_eat_escape_ecma
64 : &_Scanner::_M_eat_escape_posix)
67 template<
typename _CharT>
72 if (_M_current == _M_end)
74 _M_token = _S_token_eof;
78 if (_M_state == _S_state_normal)
80 else if (_M_state == _S_state_in_bracket)
82 else if (_M_state == _S_state_in_brace)
86 __glibcxx_assert(!
"unexpected state while processing regex");
93 template<
typename _CharT>
98 auto __c = *_M_current++;
100 if (__builtin_strchr(_M_spec_char, _M_ctype.narrow(__c,
' ')) ==
nullptr)
102 _M_token = _S_token_ord_char;
103 _M_value.assign(1, __c);
108 if (_M_current == _M_end)
110 regex_constants::error_escape,
111 "Invalid escape at end of regular expression");
114 || (*_M_current !=
'('
115 && *_M_current !=
')'
116 && *_M_current !=
'{'))
118 (this->*_M_eat_escape)();
125 if (_M_is_ecma() && *_M_current ==
'?')
127 if (++_M_current == _M_end)
128 __throw_regex_error(regex_constants::error_paren);
130 if (*_M_current ==
':')
133 _M_token = _S_token_subexpr_no_group_begin;
135 else if (*_M_current ==
'=')
138 _M_token = _S_token_subexpr_lookahead_begin;
139 _M_value.assign(1,
'p');
141 else if (*_M_current ==
'!')
144 _M_token = _S_token_subexpr_lookahead_begin;
145 _M_value.assign(1,
'n');
148 __throw_regex_error(regex_constants::error_paren,
149 "Invalid '(?...)' zero-width assertion "
150 "in regular expression");
152 else if (_M_flags & regex_constants::nosubs)
153 _M_token = _S_token_subexpr_no_group_begin;
155 _M_token = _S_token_subexpr_begin;
158 _M_token = _S_token_subexpr_end;
161 _M_state = _S_state_in_bracket;
162 _M_at_bracket_start =
true;
163 if (_M_current != _M_end && *_M_current ==
'^')
165 _M_token = _S_token_bracket_neg_begin;
169 _M_token = _S_token_bracket_begin;
173 _M_state = _S_state_in_brace;
174 _M_token = _S_token_interval_begin;
176 else if (__builtin_expect(__c == _CharT(0),
false))
179 __throw_regex_error(regex_constants::_S_null);
180 _M_token = _S_token_ord_char;
181 _M_value.assign(1, __c);
183 else if (__c !=
']' && __c !=
'}')
185 auto __it = _M_token_tbl;
186 auto __narrowc = _M_ctype.narrow(__c,
'\0');
187 for (; __it->first !=
'\0'; ++__it)
188 if (__it->first == __narrowc)
190 _M_token = __it->second;
193 __glibcxx_assert(!
"unexpected special character in regex");
197 _M_token = _S_token_ord_char;
198 _M_value.assign(1, __c);
205 template<
typename _CharT>
210 if (_M_current == _M_end)
211 __throw_regex_error(regex_constants::error_brack);
213 auto __c = *_M_current++;
216 _M_token = _S_token_bracket_dash;
219 if (_M_current == _M_end)
220 __throw_regex_error(regex_constants::error_brack,
221 "Incomplete '[[' character class in "
222 "regular expression");
224 if (*_M_current ==
'.')
226 _M_token = _S_token_collsymbol;
227 _M_eat_class(*_M_current++);
229 else if (*_M_current ==
':')
231 _M_token = _S_token_char_class_name;
232 _M_eat_class(*_M_current++);
234 else if (*_M_current ==
'=')
236 _M_token = _S_token_equiv_class_name;
237 _M_eat_class(*_M_current++);
241 _M_token = _S_token_ord_char;
242 _M_value.assign(1, __c);
248 else if (__c ==
']' && (_M_is_ecma() || !_M_at_bracket_start))
250 _M_token = _S_token_bracket_end;
251 _M_state = _S_state_normal;
254 else if (__c ==
'\\' && (_M_is_ecma() || _M_is_awk()))
255 (this->*_M_eat_escape)();
258 _M_token = _S_token_ord_char;
259 _M_value.assign(1, __c);
261 _M_at_bracket_start =
false;
266 template<
typename _CharT>
271 if (_M_current == _M_end)
272 __throw_regex_error(regex_constants::error_brace);
274 auto __c = *_M_current++;
276 if (_M_ctype.is(_CtypeT::digit, __c))
278 _M_token = _S_token_dup_count;
279 _M_value.assign(1, __c);
280 while (_M_current != _M_end
281 && _M_ctype.is(_CtypeT::digit, *_M_current))
282 _M_value += *_M_current++;
285 _M_token = _S_token_comma;
287 else if (_M_is_basic())
289 if (__c ==
'\\' && _M_current != _M_end && *_M_current ==
'}')
291 _M_state = _S_state_normal;
292 _M_token = _S_token_interval_end;
296 __throw_regex_error(regex_constants::error_badbrace);
300 _M_state = _S_state_normal;
301 _M_token = _S_token_interval_end;
304 __throw_regex_error(regex_constants::error_badbrace);
307 template<
typename _CharT>
312 if (_M_current == _M_end)
313 __throw_regex_error(regex_constants::error_escape);
315 auto __c = *_M_current++;
316 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
318 if (__pos !=
nullptr && (__c !=
'b' || _M_state == _S_state_in_bracket))
320 _M_token = _S_token_ord_char;
321 _M_value.assign(1, *__pos);
325 _M_token = _S_token_word_bound;
326 _M_value.assign(1,
'p');
330 _M_token = _S_token_word_bound;
331 _M_value.assign(1,
'n');
341 _M_token = _S_token_quoted_class;
342 _M_value.assign(1, __c);
346 if (_M_current == _M_end)
347 __throw_regex_error(regex_constants::error_escape,
348 "invalid '\\cX' control character in "
349 "regular expression");
350 _M_token = _S_token_ord_char;
351 _M_value.assign(1, *_M_current++);
353 else if (__c ==
'x' || __c ==
'u')
356 const int __n = __c ==
'x' ? 2 : 4;
357 for (
int __i = 0; __i < __n; __i++)
359 if (_M_current == _M_end
360 || !_M_ctype.is(_CtypeT::xdigit, *_M_current))
361 __throw_regex_error(regex_constants::error_escape,
363 ?
"Invalid '\\xNN' control character in "
365 :
"Invalid '\\uNNNN' control character in "
366 "regular expression");
367 _M_value += *_M_current++;
369 _M_token = _S_token_hex_num;
372 else if (_M_ctype.is(_CtypeT::digit, __c))
374 _M_value.assign(1, __c);
375 while (_M_current != _M_end
376 && _M_ctype.is(_CtypeT::digit, *_M_current))
377 _M_value += *_M_current++;
378 _M_token = _S_token_backref;
382 _M_token = _S_token_ord_char;
383 _M_value.assign(1, __c);
389 template<
typename _CharT>
392 _M_eat_escape_posix()
394 if (_M_current == _M_end)
395 __throw_regex_error(regex_constants::error_escape);
397 auto __c = *_M_current;
398 auto __pos = __builtin_strchr(_M_spec_char, _M_ctype.narrow(__c,
'\0'));
400 if (__pos !=
nullptr && *__pos !=
'\0')
402 _M_token = _S_token_ord_char;
403 _M_value.assign(1, __c);
406 else if (_M_is_awk())
411 else if (_M_is_basic() && _M_ctype.is(_CtypeT::digit, __c) && __c !=
'0')
413 _M_token = _S_token_backref;
414 _M_value.assign(1, __c);
418#ifdef __STRICT_ANSI__
420 __throw_regex_error(regex_constants::error_escape);
422 _M_token = _S_token_ord_char;
423 _M_value.assign(1, __c);
429 template<
typename _CharT>
434 auto __c = *_M_current++;
435 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
437 if (__pos !=
nullptr)
439 _M_token = _S_token_ord_char;
440 _M_value.assign(1, *__pos);
443 else if (_M_ctype.is(_CtypeT::digit, __c)
447 _M_value.assign(1, __c);
450 && _M_current != _M_end
451 && _M_ctype.is(_CtypeT::digit, *_M_current)
452 && *_M_current !=
'8'
453 && *_M_current !=
'9';
455 _M_value += *_M_current++;
456 _M_token = _S_token_oct_num;
460 __throw_regex_error(regex_constants::error_escape);
466 template<
typename _CharT>
469 _M_eat_class(
char __ch)
471 for (_M_value.clear(); _M_current != _M_end && *_M_current != __ch;)
472 _M_value += *_M_current++;
473 if (_M_current == _M_end
474 || *_M_current++ != __ch
475 || _M_current == _M_end
476 || *_M_current++ !=
']')
478 __throw_regex_error(__ch ==
':' ? regex_constants::error_ctype
484 template<
typename _CharT>
491 case _S_token_anychar:
492 ostr <<
"any-character\n";
494 case _S_token_backref:
497 case _S_token_bracket_begin:
498 ostr <<
"bracket-begin\n";
500 case _S_token_bracket_neg_begin:
501 ostr <<
"bracket-neg-begin\n";
503 case _S_token_bracket_end:
504 ostr <<
"bracket-end\n";
506 case _S_token_char_class_name:
507 ostr <<
"char-class-name \"" << _M_value <<
"\"\n";
509 case _S_token_closure0:
510 ostr <<
"closure0\n";
512 case _S_token_closure1:
513 ostr <<
"closure1\n";
515 case _S_token_collsymbol:
516 ostr <<
"collsymbol \"" << _M_value <<
"\"\n";
521 case _S_token_dup_count:
522 ostr <<
"dup count: " << _M_value <<
"\n";
527 case _S_token_equiv_class_name:
528 ostr <<
"equiv-class-name \"" << _M_value <<
"\"\n";
530 case _S_token_interval_begin:
531 ostr <<
"interval begin\n";
533 case _S_token_interval_end:
534 ostr <<
"interval end\n";
536 case _S_token_line_begin:
537 ostr <<
"line begin\n";
539 case _S_token_line_end:
540 ostr <<
"line end\n";
548 case _S_token_ord_char:
549 ostr <<
"ordinary character: \"" << _M_value <<
"\"\n";
551 case _S_token_subexpr_begin:
552 ostr <<
"subexpr begin\n";
554 case _S_token_subexpr_no_group_begin:
555 ostr <<
"no grouping subexpr begin\n";
557 case _S_token_subexpr_lookahead_begin:
558 ostr <<
"lookahead subexpr begin\n";
560 case _S_token_subexpr_end:
561 ostr <<
"subexpr end\n";
563 case _S_token_unknown:
564 ostr <<
"-- unknown token --\n";
566 case _S_token_oct_num:
567 ostr <<
"oct number " << _M_value <<
"\n";
569 case _S_token_hex_num:
570 ostr <<
"hex number " << _M_value <<
"\n";
572 case _S_token_quoted_class:
573 ostr <<
"quoted class " <<
"\\" << _M_value <<
"\n";
576 _GLIBCXX_DEBUG_ASSERT(
false);
583_GLIBCXX_END_NAMESPACE_VERSION
const _Facet & use_facet(const locale &__loc)
Return a facet.
ISO C++ entities toplevel namespace is std.
constexpr error_type error_collate(_S_error_collate)
Container class for localization functionality.