49namespace std _GLIBCXX_VISIBILITY(default)
51_GLIBCXX_BEGIN_NAMESPACE_VERSION
55 template<
typename _CharT>
57 _Scanner(
typename _Scanner::_IterT __begin,
58 typename _Scanner::_IterT __end,
60 : _ScannerBase(__flags),
61 _M_current(__begin), _M_end(__end),
63 _M_eat_escape(_M_is_ecma()
64 ? &_Scanner::_M_eat_escape_ecma
65 : &_Scanner::_M_eat_escape_posix)
68 template<
typename _CharT>
73 if (_M_current == _M_end)
75 _M_token = _S_token_eof;
79 if (_M_state == _S_state_normal)
81 else if (_M_state == _S_state_in_bracket)
83 else if (_M_state == _S_state_in_brace)
87 __glibcxx_assert(
false);
94 template<
typename _CharT>
99 auto __c = *_M_current++;
101 if (std::strchr(_M_spec_char, _M_ctype.narrow(__c,
' ')) ==
nullptr)
103 _M_token = _S_token_ord_char;
104 _M_value.assign(1, __c);
109 if (_M_current == _M_end)
111 regex_constants::error_escape,
112 "Unexpected end of regex when escaping.");
115 || (*_M_current !=
'('
116 && *_M_current !=
')'
117 && *_M_current !=
'{'))
119 (this->*_M_eat_escape)();
126 if (_M_is_ecma() && *_M_current ==
'?')
128 if (++_M_current == _M_end)
130 regex_constants::error_paren,
131 "Unexpected end of regex when in an open parenthesis.");
133 if (*_M_current ==
':')
136 _M_token = _S_token_subexpr_no_group_begin;
138 else if (*_M_current ==
'=')
141 _M_token = _S_token_subexpr_lookahead_begin;
142 _M_value.assign(1,
'p');
144 else if (*_M_current ==
'!')
147 _M_token = _S_token_subexpr_lookahead_begin;
148 _M_value.assign(1,
'n');
152 regex_constants::error_paren,
153 "Invalid special open parenthesis.");
155 else if (_M_flags & regex_constants::nosubs)
156 _M_token = _S_token_subexpr_no_group_begin;
158 _M_token = _S_token_subexpr_begin;
161 _M_token = _S_token_subexpr_end;
164 _M_state = _S_state_in_bracket;
165 _M_at_bracket_start =
true;
166 if (_M_current != _M_end && *_M_current ==
'^')
168 _M_token = _S_token_bracket_neg_begin;
172 _M_token = _S_token_bracket_begin;
176 _M_state = _S_state_in_brace;
177 _M_token = _S_token_interval_begin;
179 else if (__builtin_expect(__c == _CharT(0),
false))
183 __throw_regex_error(regex_constants::_S_null,
184 "Unexpected null character in regular expression");
186 _M_token = _S_token_ord_char;
187 _M_value.assign(1, __c);
189 else if (__c !=
']' && __c !=
'}')
191 auto __it = _M_token_tbl;
192 auto __narrowc = _M_ctype.narrow(__c,
'\0');
193 for (; __it->first !=
'\0'; ++__it)
194 if (__it->first == __narrowc)
196 _M_token = __it->second;
199 __glibcxx_assert(
false);
203 _M_token = _S_token_ord_char;
204 _M_value.assign(1, __c);
211 template<
typename _CharT>
216 if (_M_current == _M_end)
218 regex_constants::error_brack,
219 "Unexpected end of regex when in bracket expression.");
221 auto __c = *_M_current++;
224 _M_token = _S_token_bracket_dash;
227 if (_M_current == _M_end)
228 __throw_regex_error(regex_constants::error_brack,
229 "Unexpected character class open bracket.");
231 if (*_M_current ==
'.')
233 _M_token = _S_token_collsymbol;
234 _M_eat_class(*_M_current++);
236 else if (*_M_current ==
':')
238 _M_token = _S_token_char_class_name;
239 _M_eat_class(*_M_current++);
241 else if (*_M_current ==
'=')
243 _M_token = _S_token_equiv_class_name;
244 _M_eat_class(*_M_current++);
248 _M_token = _S_token_ord_char;
249 _M_value.assign(1, __c);
255 else if (__c ==
']' && (_M_is_ecma() || !_M_at_bracket_start))
257 _M_token = _S_token_bracket_end;
258 _M_state = _S_state_normal;
261 else if (__c ==
'\\' && (_M_is_ecma() || _M_is_awk()))
262 (this->*_M_eat_escape)();
265 _M_token = _S_token_ord_char;
266 _M_value.assign(1, __c);
268 _M_at_bracket_start =
false;
273 template<
typename _CharT>
278 if (_M_current == _M_end)
280 regex_constants::error_brace,
281 "Unexpected end of regex when in brace expression.");
283 auto __c = *_M_current++;
285 if (_M_ctype.is(_CtypeT::digit, __c))
287 _M_token = _S_token_dup_count;
288 _M_value.assign(1, __c);
289 while (_M_current != _M_end
290 && _M_ctype.is(_CtypeT::digit, *_M_current))
291 _M_value += *_M_current++;
294 _M_token = _S_token_comma;
296 else if (_M_is_basic())
298 if (__c ==
'\\' && _M_current != _M_end && *_M_current ==
'}')
300 _M_state = _S_state_normal;
301 _M_token = _S_token_interval_end;
305 __throw_regex_error(regex_constants::error_badbrace,
306 "Unexpected character in brace expression.");
310 _M_state = _S_state_normal;
311 _M_token = _S_token_interval_end;
314 __throw_regex_error(regex_constants::error_badbrace,
315 "Unexpected character in brace expression.");
318 template<
typename _CharT>
323 if (_M_current == _M_end)
324 __throw_regex_error(regex_constants::error_escape,
325 "Unexpected end of regex when escaping.");
327 auto __c = *_M_current++;
328 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
330 if (__pos !=
nullptr && (__c !=
'b' || _M_state == _S_state_in_bracket))
332 _M_token = _S_token_ord_char;
333 _M_value.assign(1, *__pos);
337 _M_token = _S_token_word_bound;
338 _M_value.assign(1,
'p');
342 _M_token = _S_token_word_bound;
343 _M_value.assign(1,
'n');
353 _M_token = _S_token_quoted_class;
354 _M_value.assign(1, __c);
358 if (_M_current == _M_end)
360 regex_constants::error_escape,
361 "Unexpected end of regex when reading control code.");
362 _M_token = _S_token_ord_char;
363 _M_value.assign(1, *_M_current++);
365 else if (__c ==
'x' || __c ==
'u')
368 for (
int __i = 0; __i < (__c ==
'x' ? 2 : 4); __i++)
370 if (_M_current == _M_end
371 || !_M_ctype.is(_CtypeT::xdigit, *_M_current))
373 regex_constants::error_escape,
374 "Unexpected end of regex when ascii character.");
375 _M_value += *_M_current++;
377 _M_token = _S_token_hex_num;
380 else if (_M_ctype.is(_CtypeT::digit, __c))
382 _M_value.assign(1, __c);
383 while (_M_current != _M_end
384 && _M_ctype.is(_CtypeT::digit, *_M_current))
385 _M_value += *_M_current++;
386 _M_token = _S_token_backref;
390 _M_token = _S_token_ord_char;
391 _M_value.assign(1, __c);
397 template<
typename _CharT>
400 _M_eat_escape_posix()
402 if (_M_current == _M_end)
403 __throw_regex_error(regex_constants::error_escape,
404 "Unexpected end of regex when escaping.");
406 auto __c = *_M_current;
407 auto __pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c,
'\0'));
409 if (__pos !=
nullptr && *__pos !=
'\0')
411 _M_token = _S_token_ord_char;
412 _M_value.assign(1, __c);
415 else if (_M_is_awk())
420 else if (_M_is_basic() && _M_ctype.is(_CtypeT::digit, __c) && __c !=
'0')
422 _M_token = _S_token_backref;
423 _M_value.assign(1, __c);
427#ifdef __STRICT_ANSI__
429 __throw_regex_error(regex_constants::error_escape,
430 "Unexpected escape character.");
432 _M_token = _S_token_ord_char;
433 _M_value.assign(1, __c);
439 template<
typename _CharT>
444 auto __c = *_M_current++;
445 auto __pos = _M_find_escape(_M_ctype.narrow(__c,
'\0'));
447 if (__pos !=
nullptr)
449 _M_token = _S_token_ord_char;
450 _M_value.assign(1, *__pos);
453 else if (_M_ctype.is(_CtypeT::digit, __c)
457 _M_value.assign(1, __c);
460 && _M_current != _M_end
461 && _M_ctype.is(_CtypeT::digit, *_M_current)
462 && *_M_current !=
'8'
463 && *_M_current !=
'9';
465 _M_value += *_M_current++;
466 _M_token = _S_token_oct_num;
470 __throw_regex_error(regex_constants::error_escape,
471 "Unexpected escape character.");
477 template<
typename _CharT>
480 _M_eat_class(
char __ch)
482 for (_M_value.clear(); _M_current != _M_end && *_M_current != __ch;)
483 _M_value += *_M_current++;
484 if (_M_current == _M_end
485 || *_M_current++ != __ch
486 || _M_current == _M_end
487 || *_M_current++ !=
']')
490 __throw_regex_error(regex_constants::error_ctype,
491 "Unexpected end of character class.");
493 __throw_regex_error(regex_constants::error_collate,
494 "Unexpected end of character class.");
499 template<
typename _CharT>
506 case _S_token_anychar:
507 ostr <<
"any-character\n";
509 case _S_token_backref:
512 case _S_token_bracket_begin:
513 ostr <<
"bracket-begin\n";
515 case _S_token_bracket_neg_begin:
516 ostr <<
"bracket-neg-begin\n";
518 case _S_token_bracket_end:
519 ostr <<
"bracket-end\n";
521 case _S_token_char_class_name:
522 ostr <<
"char-class-name \"" << _M_value <<
"\"\n";
524 case _S_token_closure0:
525 ostr <<
"closure0\n";
527 case _S_token_closure1:
528 ostr <<
"closure1\n";
530 case _S_token_collsymbol:
531 ostr <<
"collsymbol \"" << _M_value <<
"\"\n";
536 case _S_token_dup_count:
537 ostr <<
"dup count: " << _M_value <<
"\n";
542 case _S_token_equiv_class_name:
543 ostr <<
"equiv-class-name \"" << _M_value <<
"\"\n";
545 case _S_token_interval_begin:
546 ostr <<
"interval begin\n";
548 case _S_token_interval_end:
549 ostr <<
"interval end\n";
551 case _S_token_line_begin:
552 ostr <<
"line begin\n";
554 case _S_token_line_end:
555 ostr <<
"line end\n";
563 case _S_token_ord_char:
564 ostr <<
"ordinary character: \"" << _M_value <<
"\"\n";
566 case _S_token_subexpr_begin:
567 ostr <<
"subexpr begin\n";
569 case _S_token_subexpr_no_group_begin:
570 ostr <<
"no grouping subexpr begin\n";
572 case _S_token_subexpr_lookahead_begin:
573 ostr <<
"lookahead subexpr begin\n";
575 case _S_token_subexpr_end:
576 ostr <<
"subexpr end\n";
578 case _S_token_unknown:
579 ostr <<
"-- unknown token --\n";
581 case _S_token_oct_num:
582 ostr <<
"oct number " << _M_value <<
"\n";
584 case _S_token_hex_num:
585 ostr <<
"hex number " << _M_value <<
"\n";
587 case _S_token_quoted_class:
588 ostr <<
"quoted class " <<
"\\" << _M_value <<
"\n";
591 _GLIBCXX_DEBUG_ASSERT(
false);
598_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.