58#pragma GCC diagnostic push
59#pragma GCC diagnostic ignored "-Wc++20-extensions"
61namespace std _GLIBCXX_VISIBILITY(default)
63_GLIBCXX_BEGIN_NAMESPACE_VERSION
67 template<
typename _TraitsT>
69 _Compiler(
const _CharT* __b,
const _CharT* __e,
70 const typename _TraitsT::locale_type& __loc, _FlagT __flags)
71 : _M_flags(_S_validate(__flags)),
72 _M_scanner(__b, __e, _M_flags, __loc),
74 _M_traits(_M_nfa->_M_traits),
77 _StateSeqT __r(*_M_nfa, _M_nfa->_M_start());
78 __r._M_append(_M_nfa->_M_insert_subexpr_begin());
79 this->_M_disjunction();
80 if (!_M_match_token(_ScannerT::_S_token_eof))
81 __throw_regex_error(regex_constants::error_paren);
82 __r._M_append(_M_pop());
83 __glibcxx_assert(_M_stack.empty());
84 __r._M_append(_M_nfa->_M_insert_subexpr_end());
85 __r._M_append(_M_nfa->_M_insert_accept());
86 _M_nfa->_M_eliminate_dummy();
89 template<
typename _TraitsT>
94 this->_M_alternative();
95 while (_M_match_token(_ScannerT::_S_token_or))
97 _StateSeqT __alt1 = _M_pop();
98 this->_M_alternative();
99 _StateSeqT __alt2 = _M_pop();
100 auto __end = _M_nfa->_M_insert_dummy();
101 __alt1._M_append(__end);
102 __alt2._M_append(__end);
106 _M_stack.push(_StateSeqT(*_M_nfa,
107 _M_nfa->_M_insert_alt(
108 __alt2._M_start, __alt1._M_start,
false),
113 template<
typename _TraitsT>
115 _Compiler<_TraitsT>::
120 _StateSeqT __re = _M_pop();
121 this->_M_alternative();
122 __re._M_append(_M_pop());
126 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_dummy()));
129 template<
typename _TraitsT>
131 _Compiler<_TraitsT>::
134 if (this->_M_assertion())
138 while (this->_M_quantifier())
145 template<
typename _TraitsT>
147 _Compiler<_TraitsT>::
150 if (_M_match_token(_ScannerT::_S_token_line_begin))
151 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_begin()));
152 else if (_M_match_token(_ScannerT::_S_token_line_end))
153 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_end()));
154 else if (_M_match_token(_ScannerT::_S_token_word_bound))
156 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->
157 _M_insert_word_bound(_M_value[0] ==
'n')));
158 else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin))
160 auto __neg = _M_value[0] ==
'n';
161 this->_M_disjunction();
162 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
163 __throw_regex_error(regex_constants::error_paren);
164 auto __tmp = _M_pop();
165 __tmp._M_append(_M_nfa->_M_insert_accept());
169 _M_nfa->_M_insert_lookahead(__tmp._M_start, __neg)));
176 template<
typename _TraitsT>
178 _Compiler<_TraitsT>::
181 bool __neg = (_M_flags & regex_constants::ECMAScript);
182 auto __init = [
this, &__neg]()
184 if (_M_stack.empty())
185 __throw_regex_error(regex_constants::error_badrepeat);
186 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
188 if (_M_match_token(_ScannerT::_S_token_closure0))
192 _StateSeqT __r(*_M_nfa,
193 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
194 __e._M_start, __neg));
198 else if (_M_match_token(_ScannerT::_S_token_closure1))
202 __e._M_append(_M_nfa->_M_insert_repeat(_S_invalid_state_id,
203 __e._M_start, __neg));
206 else if (_M_match_token(_ScannerT::_S_token_opt))
210 auto __end = _M_nfa->_M_insert_dummy();
211 _StateSeqT __r(*_M_nfa,
212 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
213 __e._M_start, __neg));
214 __e._M_append(__end);
215 __r._M_append(__end);
218 else if (_M_match_token(_ScannerT::_S_token_interval_begin))
220 if (_M_stack.empty())
221 __throw_regex_error(regex_constants::error_badrepeat);
222 if (!_M_match_token(_ScannerT::_S_token_dup_count))
223 __throw_regex_error(regex_constants::error_badbrace);
224 _StateSeqT __r(_M_pop());
225 _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy());
226 long __min_rep = _M_cur_int_value(10);
231 if (_M_match_token(_ScannerT::_S_token_comma))
233 if (_M_match_token(_ScannerT::_S_token_dup_count))
234 __n = _M_cur_int_value(10) - __min_rep;
238 if (!_M_match_token(_ScannerT::_S_token_interval_end))
239 __throw_regex_error(regex_constants::error_brace);
241 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
243 for (
long __i = 0; __i < __min_rep; ++__i)
244 __e._M_append(__r._M_clone());
248 auto __tmp = __r._M_clone();
249 _StateSeqT __s(*_M_nfa,
250 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
251 __tmp._M_start, __neg));
252 __tmp._M_append(__s);
258 __throw_regex_error(regex_constants::error_badbrace);
259 auto __end = _M_nfa->_M_insert_dummy();
264 for (
long __i = 0; __i < __n; ++__i)
266 auto __tmp = __r._M_clone();
267 auto __alt = _M_nfa->_M_insert_repeat(__tmp._M_start,
270 __e._M_append(_StateSeqT(*_M_nfa, __alt, __tmp._M_end));
272 __e._M_append(__end);
273 while (!__stack.
empty())
275 auto& __tmp = (*_M_nfa)[__stack.
top()];
277 std::swap(__tmp._M_next, __tmp._M_alt);
287#define __INSERT_REGEX_MATCHER(__func, ...)\
289 if (!(_M_flags & regex_constants::icase))\
290 if (!(_M_flags & regex_constants::collate))\
291 __func<false, false>(__VA_ARGS__);\
293 __func<false, true>(__VA_ARGS__);\
295 if (!(_M_flags & regex_constants::collate))\
296 __func<true, false>(__VA_ARGS__);\
298 __func<true, true>(__VA_ARGS__);\
301 template<
typename _TraitsT>
303 _Compiler<_TraitsT>::
306 if (_M_match_token(_ScannerT::_S_token_anychar))
308 if (!(_M_flags & regex_constants::ECMAScript))
309 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_posix);
311 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_ecma);
313 else if (_M_try_char())
314 __INSERT_REGEX_MATCHER(_M_insert_char_matcher);
315 else if (_M_match_token(_ScannerT::_S_token_backref))
316 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->
317 _M_insert_backref(_M_cur_int_value(10))));
318 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
319 __INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
320 else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin))
322 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_dummy());
323 this->_M_disjunction();
324 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
325 __throw_regex_error(regex_constants::error_paren);
326 __r._M_append(_M_pop());
329 else if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
331 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_subexpr_begin());
332 this->_M_disjunction();
333 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
334 __throw_regex_error(regex_constants::error_paren);
335 __r._M_append(_M_pop());
336 __r._M_append(_M_nfa->_M_insert_subexpr_end());
339 else if (!_M_bracket_expression())
344 template<
typename _TraitsT>
346 _Compiler<_TraitsT>::
347 _M_bracket_expression()
350 _M_match_token(_ScannerT::_S_token_bracket_neg_begin);
351 if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin)))
353 __INSERT_REGEX_MATCHER(_M_insert_bracket_matcher, __neg);
356#undef __INSERT_REGEX_MATCHER
358 template<
typename _TraitsT>
359 template<
bool __icase,
bool __collate>
361 _Compiler<_TraitsT>::
362 _M_insert_any_matcher_ecma()
364 _M_stack.push(_StateSeqT(*_M_nfa,
365 _M_nfa->_M_insert_matcher
366 (_AnyMatcher<_TraitsT, true, __icase, __collate>
370 template<
typename _TraitsT>
371 template<
bool __icase,
bool __collate>
373 _Compiler<_TraitsT>::
374 _M_insert_any_matcher_posix()
376 _M_stack.push(_StateSeqT(*_M_nfa,
377 _M_nfa->_M_insert_matcher
378 (_AnyMatcher<_TraitsT, false, __icase, __collate>
382 template<
typename _TraitsT>
383 template<
bool __icase,
bool __collate>
385 _Compiler<_TraitsT>::
386 _M_insert_char_matcher()
388 _M_stack.push(_StateSeqT(*_M_nfa,
389 _M_nfa->_M_insert_matcher
390 (_CharMatcher<_TraitsT, __icase, __collate>
391 (_M_value[0], _M_traits))));
394 template<
typename _TraitsT>
395 template<
bool __icase,
bool __collate>
397 _Compiler<_TraitsT>::
398 _M_insert_character_class_matcher()
400 __glibcxx_assert(_M_value.size() == 1);
401 _BracketMatcher<__icase, __collate> __matcher
402 (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits);
403 __matcher._M_add_character_class(_M_value,
false);
404 __matcher._M_ready();
405 _M_stack.push(_StateSeqT(*_M_nfa,
406 _M_nfa->_M_insert_matcher(
std::move(__matcher))));
409 template<
typename _TraitsT>
410 template<
bool __icase,
bool __collate>
412 _Compiler<_TraitsT>::
413 _M_insert_bracket_matcher(
bool __neg)
415 _BracketMatcher<__icase, __collate> __matcher(__neg, _M_traits);
416 _BracketState __last_char;
418 __last_char.set(_M_value[0]);
419 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
421 __last_char.set(
'-');
422 while (_M_expression_term(__last_char, __matcher))
424 if (__last_char._M_is_char())
425 __matcher._M_add_char(__last_char.get());
426 __matcher._M_ready();
427 _M_stack.push(_StateSeqT(
429 _M_nfa->_M_insert_matcher(
std::move(__matcher))));
432 template<
typename _TraitsT>
433 template<
bool __icase,
bool __collate>
435 _Compiler<_TraitsT>::
436 _M_expression_term(_BracketState& __last_char,
437 _BracketMatcher<__icase, __collate>& __matcher)
439 if (_M_match_token(_ScannerT::_S_token_bracket_end))
443 const auto __push_char = [&](_CharT __ch)
445 if (__last_char._M_is_char())
446 __matcher._M_add_char(__last_char.get());
447 __last_char.set(__ch);
450 const auto __push_class = [&]
452 if (__last_char._M_is_char())
453 __matcher._M_add_char(__last_char.get());
456 __last_char.reset(_BracketState::_Type::_Class);
459 if (_M_match_token(_ScannerT::_S_token_collsymbol))
461 auto __symbol = __matcher._M_add_collate_element(_M_value);
462 if (__symbol.size() == 1)
463 __push_char(__symbol[0]);
467 else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
470 __matcher._M_add_equivalence_class(_M_value);
472 else if (_M_match_token(_ScannerT::_S_token_char_class_name))
475 __matcher._M_add_character_class(_M_value,
false);
477 else if (_M_try_char())
478 __push_char(_M_value[0]);
489 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
491 if (_M_match_token(_ScannerT::_S_token_bracket_end))
497 else if (__last_char._M_is_class())
500 __throw_regex_error(regex_constants::error_range,
501 "Invalid start of '[x-x]' range in "
502 "regular expression");
504 else if (__last_char._M_is_char())
509 __matcher._M_make_range(__last_char.get(), _M_value[0]);
512 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
515 __matcher._M_make_range(__last_char.get(),
'-');
519 __throw_regex_error(regex_constants::error_range,
520 "Invalid end of '[x-x]' range in "
521 "regular expression");
523 else if (_M_flags & regex_constants::ECMAScript)
531 __throw_regex_error(regex_constants::error_range,
532 "Invalid location of '-' within '[...]' in "
533 "POSIX regular expression");
535 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
538 __matcher._M_add_character_class(_M_value,
539 _M_ctype.is(_CtypeT::upper,
543 __throw_regex_error(regex_constants::error_brack,
544 "Unexpected character within '[...]' in "
545 "regular expression");
549 template<
typename _TraitsT>
551 _Compiler<_TraitsT>::
554 bool __is_char =
false;
555 if (_M_match_token(_ScannerT::_S_token_oct_num))
558 _M_value.assign(1, _M_cur_int_value(8));
560 else if (_M_match_token(_ScannerT::_S_token_hex_num))
563 _M_value.assign(1, _M_cur_int_value(16));
565 else if (_M_match_token(_ScannerT::_S_token_ord_char))
570 template<
typename _TraitsT>
572 _Compiler<_TraitsT>::
573 _M_match_token(_TokenT __token)
575 if (__token == _M_scanner._M_get_token())
577 _M_value = _M_scanner._M_get_value();
578 _M_scanner._M_advance();
584 template<
typename _TraitsT>
586 _Compiler<_TraitsT>::
587 _M_cur_int_value(
int __radix)
590 for (_CharT __c : _M_value)
591 if (__builtin_mul_overflow(__v, __radix, &__v)
592 || __builtin_add_overflow(__v, _M_traits.value(__c, __radix), &__v))
593 std::__throw_regex_error(regex_constants::error_backref,
594 "invalid back reference");
598 template<
typename _TraitsT,
bool __icase,
bool __collate>
600 _BracketMatcher<_TraitsT, __icase, __collate>::
601 _M_apply(_CharT __ch)
const
605 if (std::binary_search(_M_char_set.begin(), _M_char_set.end(),
606 _M_translator._M_translate(__ch)))
608 auto __s = _M_translator._M_transform(__ch);
609 for (
auto& __it : _M_range_set)
610 if (_M_translator._M_match_range(__it.first, __it.second, __s))
612 if (_M_traits.isctype(__ch, _M_class_set))
614 if (!_M_equiv_set.empty())
616 auto __x = _M_traits.transform_primary(&__ch, &__ch+1);
617 auto __p = std::find(_M_equiv_set.begin(), _M_equiv_set.end(), __x);
618 if (__p != _M_equiv_set.end())
621 for (
auto& __it : _M_neg_class_set)
622 if (!_M_traits.isctype(__ch, __it))
625 }() ^ _M_is_non_matching;
629_GLIBCXX_END_NAMESPACE_VERSION
632#pragma GCC diagnostic pop
shared_ptr< _NonArray< _Tp > > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
const _Facet & use_facet(const locale &__loc)
Return a facet.
ISO C++ entities toplevel namespace is std.
Implementation details not part of the namespace std interface.
Builds an NFA from an input iterator range.
A standard container giving FILO behavior.
void pop()
Removes first element.
void push(const value_type &__x)
Add data to the top of the stack.