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(
false);
93 template<
typename _CharT>
98 auto __c = *_M_current++;
100 if (std::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 "Unexpected end of regex when escaping.");
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)
129 regex_constants::error_paren,
130 "Unexpected end of regex when in an open parenthesis.");
132 if (*_M_current ==
':')
135 _M_token = _S_token_subexpr_no_group_begin;
137 else if (*_M_current ==
'=')
140 _M_token = _S_token_subexpr_lookahead_begin;
141 _M_value.assign(1,
'p');
143 else if (*_M_current ==
'!')
146 _M_token = _S_token_subexpr_lookahead_begin;
147 _M_value.assign(1,
'n');
151 regex_constants::error_paren,
152 "Invalid special open parenthesis.");
154 else if (_M_flags & regex_constants::nosubs)
155 _M_token = _S_token_subexpr_no_group_begin;
157 _M_token = _S_token_subexpr_begin;
160 _M_token = _S_token_subexpr_end;
163 _M_state = _S_state_in_bracket;
164 _M_at_bracket_start =
true;
165 if (_M_current != _M_end && *_M_current ==
'^')
167 _M_token = _S_token_bracket_neg_begin;
171 _M_token = _S_token_bracket_begin;
175 _M_state = _S_state_in_brace;
176 _M_token = _S_token_interval_begin;
178 else if (__builtin_expect(__c == _CharT(0),
false))
182 __throw_regex_error(regex_constants::_S_null,
183 "Unexpected null character in regular expression");
185 _M_token = _S_token_ord_char;
186 _M_value.assign(1, __c);
188 else if (__c !=
']' && __c !=
'}')
190 auto __it = _M_token_tbl;
191 auto __narrowc = _M_ctype.narrow(__c,
'\0');
192 for (; __it->first !=
'\0'; ++__it)
193 if (__it->first == __narrowc)
195 _M_token = __it->second;
198 __glibcxx_assert(
false);
202 _M_token = _S_token_ord_char;
203 _M_value.assign(1, __c);
210 template<
typename _CharT>
215 if (_M_current == _M_end)
217 regex_constants::error_brack,
218 "Unexpected end of regex when in bracket expression.");
220 auto __c = *_M_current++;
223 _M_token = _S_token_bracket_dash;
226 if (_M_current == _M_end)
227 __throw_regex_error(regex_constants::error_brack,
228 "Unexpected character class open bracket.");
230 if (*_M_current ==
'.')
232 _M_token = _S_token_collsymbol;
233 _M_eat_class(*_M_current++);
235 else if (*_M_current ==
':')
237 _M_token = _S_token_char_class_name;
238 _M_eat_class(*_M_current++);
240 else if (*_M_current ==
'=')
242 _M_token = _S_token_equiv_class_name;
243 _M_eat_class(*_M_current++);
247 _M_token = _S_token_ord_char;
248 _M_value.assign(1, __c);
254 else if (__c ==
']' && (_M_is_ecma() || !_M_at_bracket_start))
256 _M_token = _S_token_bracket_end;
257 _M_state = _S_state_normal;
260 else if (__c ==
'\\' && (_M_is_ecma() || _M_is_awk()))
261 (this->*_M_eat_escape)();
264 _M_token = _S_token_ord_char;
265 _M_value.assign(1, __c);
267 _M_at_bracket_start =
false;
272 template<
typename _CharT>
277 if (_M_current == _M_end)
279 regex_constants::error_brace,
280 "Unexpected end of regex when in brace expression.");
282 auto __c = *_M_current++;
284 if (_M_ctype.is(_CtypeT::digit, __c))
286 _M_token = _S_token_dup_count;
287 _M_value.assign(1, __c);
288 while (_M_current != _M_end
289 && _M_ctype.is(_CtypeT::digit, *_M_current))
290 _M_value += *_M_current++;
293 _M_token = _S_token_comma;
295 else if (_M_is_basic())
297 if (__c ==
'\\' && _M_current != _M_end && *_M_current ==
'}')
299 _M_state = _S_state_normal;
300 _M_token = _S_token_interval_end;
304 __throw_regex_error(regex_constants::error_badbrace,
305 "Unexpected character in brace expression.");
309 _M_state = _S_state_normal;
310 _M_token = _S_token_interval_end;
313 __throw_regex_error(regex_constants::error_badbrace,
314 "Unexpected character in brace expression.");
317 template<
typename _CharT>
322 if (_M_current == _M_end)
323 __throw_regex_error(regex_constants::error_escape,
324 "Unexpected end of regex when escaping.");
326 auto __c = *_M_current++;
327 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
329 if (__pos !=
nullptr && (__c !=
'b' || _M_state == _S_state_in_bracket))
331 _M_token = _S_token_ord_char;
332 _M_value.assign(1, *__pos);
336 _M_token = _S_token_word_bound;
337 _M_value.assign(1,
'p');
341 _M_token = _S_token_word_bound;
342 _M_value.assign(1,
'n');
352 _M_token = _S_token_quoted_class;
353 _M_value.assign(1, __c);
357 if (_M_current == _M_end)
359 regex_constants::error_escape,
360 "Unexpected end of regex when reading control code.");
361 _M_token = _S_token_ord_char;
362 _M_value.assign(1, *_M_current++);
364 else if (__c ==
'x' || __c ==
'u')
367 for (
int __i = 0; __i < (__c ==
'x' ? 2 : 4); __i++)
369 if (_M_current == _M_end
370 || !_M_ctype.is(_CtypeT::xdigit, *_M_current))
372 regex_constants::error_escape,
373 "Unexpected end of regex when ascii character.");
374 _M_value += *_M_current++;
376 _M_token = _S_token_hex_num;
379 else if (_M_ctype.is(_CtypeT::digit, __c))
381 _M_value.assign(1, __c);
382 while (_M_current != _M_end
383 && _M_ctype.is(_CtypeT::digit, *_M_current))
384 _M_value += *_M_current++;
385 _M_token = _S_token_backref;
389 _M_token = _S_token_ord_char;
390 _M_value.assign(1, __c);
396 template<
typename _CharT>
399 _M_eat_escape_posix()
401 if (_M_current == _M_end)
402 __throw_regex_error(regex_constants::error_escape,
403 "Unexpected end of regex when escaping.");
405 auto __c = *_M_current;
406 auto __pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c,
'\0'));
408 if (__pos !=
nullptr && *__pos !=
'\0')
410 _M_token = _S_token_ord_char;
411 _M_value.assign(1, __c);
414 else if (_M_is_awk())
419 else if (_M_is_basic() && _M_ctype.is(_CtypeT::digit, __c) && __c !=
'0')
421 _M_token = _S_token_backref;
422 _M_value.assign(1, __c);
426#ifdef __STRICT_ANSI__
428 __throw_regex_error(regex_constants::error_escape,
429 "Unexpected escape character.");
431 _M_token = _S_token_ord_char;
432 _M_value.assign(1, __c);
438 template<
typename _CharT>
443 auto __c = *_M_current++;
444 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
446 if (__pos !=
nullptr)
448 _M_token = _S_token_ord_char;
449 _M_value.assign(1, *__pos);
452 else if (_M_ctype.is(_CtypeT::digit, __c)
456 _M_value.assign(1, __c);
459 && _M_current != _M_end
460 && _M_ctype.is(_CtypeT::digit, *_M_current)
461 && *_M_current !=
'8'
462 && *_M_current !=
'9';
464 _M_value += *_M_current++;
465 _M_token = _S_token_oct_num;
469 __throw_regex_error(regex_constants::error_escape,
470 "Unexpected escape character.");
476 template<
typename _CharT>
479 _M_eat_class(
char __ch)
481 for (_M_value.clear(); _M_current != _M_end && *_M_current != __ch;)
482 _M_value += *_M_current++;
483 if (_M_current == _M_end
484 || *_M_current++ != __ch
485 || _M_current == _M_end
486 || *_M_current++ !=
']')
489 __throw_regex_error(regex_constants::error_ctype,
490 "Unexpected end of character class.");
492 __throw_regex_error(regex_constants::error_collate,
493 "Unexpected end of character class.");
498 template<
typename _CharT>
505 case _S_token_anychar:
506 ostr <<
"any-character\n";
508 case _S_token_backref:
511 case _S_token_bracket_begin:
512 ostr <<
"bracket-begin\n";
514 case _S_token_bracket_neg_begin:
515 ostr <<
"bracket-neg-begin\n";
517 case _S_token_bracket_end:
518 ostr <<
"bracket-end\n";
520 case _S_token_char_class_name:
521 ostr <<
"char-class-name \"" << _M_value <<
"\"\n";
523 case _S_token_closure0:
524 ostr <<
"closure0\n";
526 case _S_token_closure1:
527 ostr <<
"closure1\n";
529 case _S_token_collsymbol:
530 ostr <<
"collsymbol \"" << _M_value <<
"\"\n";
535 case _S_token_dup_count:
536 ostr <<
"dup count: " << _M_value <<
"\n";
541 case _S_token_equiv_class_name:
542 ostr <<
"equiv-class-name \"" << _M_value <<
"\"\n";
544 case _S_token_interval_begin:
545 ostr <<
"interval begin\n";
547 case _S_token_interval_end:
548 ostr <<
"interval end\n";
550 case _S_token_line_begin:
551 ostr <<
"line begin\n";
553 case _S_token_line_end:
554 ostr <<
"line end\n";
562 case _S_token_ord_char:
563 ostr <<
"ordinary character: \"" << _M_value <<
"\"\n";
565 case _S_token_subexpr_begin:
566 ostr <<
"subexpr begin\n";
568 case _S_token_subexpr_no_group_begin:
569 ostr <<
"no grouping subexpr begin\n";
571 case _S_token_subexpr_lookahead_begin:
572 ostr <<
"lookahead subexpr begin\n";
574 case _S_token_subexpr_end:
575 ostr <<
"subexpr end\n";
577 case _S_token_unknown:
578 ostr <<
"-- unknown token --\n";
580 case _S_token_oct_num:
581 ostr <<
"oct number " << _M_value <<
"\n";
583 case _S_token_hex_num:
584 ostr <<
"hex number " << _M_value <<
"\n";
586 case _S_token_quoted_class:
587 ostr <<
"quoted class " <<
"\\" << _M_value <<
"\n";
590 _GLIBCXX_DEBUG_ASSERT(
false);
597_GLIBCXX_END_NAMESPACE_VERSION
const _Facet & use_facet(const locale &__loc)
Return a facet.
ISO C++ entities toplevel namespace is std.
Container class for localization functionality.