58 namespace std _GLIBCXX_VISIBILITY(default)
60 _GLIBCXX_BEGIN_NAMESPACE_VERSION
64 template<
typename _TraitsT>
66 _Compiler(_IterT __b, _IterT __e,
67 const typename _TraitsT::locale_type& __loc, _FlagT __flags)
70 | regex_constants::
basic 72 | regex_constants::
grep 73 | regex_constants::
egrep 74 | regex_constants::
awk))
77 _M_scanner(__b, __e, _M_flags, __loc),
79 _M_traits(_M_nfa->_M_traits),
82 _StateSeqT __r(*_M_nfa, _M_nfa->_M_start());
83 __r._M_append(_M_nfa->_M_insert_subexpr_begin());
84 this->_M_disjunction();
85 if (!_M_match_token(_ScannerT::_S_token_eof))
87 __r._M_append(_M_pop());
88 __glibcxx_assert(_M_stack.
empty());
89 __r._M_append(_M_nfa->_M_insert_subexpr_end());
90 __r._M_append(_M_nfa->_M_insert_accept());
91 _M_nfa->_M_eliminate_dummy();
94 template<
typename _TraitsT>
99 this->_M_alternative();
100 while (_M_match_token(_ScannerT::_S_token_or))
102 _StateSeqT __alt1 = _M_pop();
103 this->_M_alternative();
104 _StateSeqT __alt2 = _M_pop();
105 auto __end = _M_nfa->_M_insert_dummy();
106 __alt1._M_append(__end);
107 __alt2._M_append(__end);
111 _M_stack.push(_StateSeqT(*_M_nfa,
112 _M_nfa->_M_insert_alt(
113 __alt2._M_start, __alt1._M_start,
false),
118 template<
typename _TraitsT>
120 _Compiler<_TraitsT>::
125 _StateSeqT __re = _M_pop();
126 this->_M_alternative();
127 __re._M_append(_M_pop());
131 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_dummy()));
134 template<
typename _TraitsT>
136 _Compiler<_TraitsT>::
139 if (this->_M_assertion())
143 while (this->_M_quantifier())
150 template<
typename _TraitsT>
152 _Compiler<_TraitsT>::
155 if (_M_match_token(_ScannerT::_S_token_line_begin))
156 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_begin()));
157 else if (_M_match_token(_ScannerT::_S_token_line_end))
158 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_end()));
159 else if (_M_match_token(_ScannerT::_S_token_word_bound))
161 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->
162 _M_insert_word_bound(_M_value[0] ==
'n')));
163 else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin))
165 auto __neg = _M_value[0] ==
'n';
166 this->_M_disjunction();
167 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
169 "Parenthesis is not closed.");
170 auto __tmp = _M_pop();
171 __tmp._M_append(_M_nfa->_M_insert_accept());
175 _M_nfa->_M_insert_lookahead(__tmp._M_start, __neg)));
182 template<
typename _TraitsT>
184 _Compiler<_TraitsT>::
188 auto __init = [
this, &__neg]()
190 if (_M_stack.empty())
192 "Nothing to repeat before a quantifier.");
193 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
195 if (_M_match_token(_ScannerT::_S_token_closure0))
199 _StateSeqT __r(*_M_nfa,
200 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
201 __e._M_start, __neg));
205 else if (_M_match_token(_ScannerT::_S_token_closure1))
209 __e._M_append(_M_nfa->_M_insert_repeat(_S_invalid_state_id,
210 __e._M_start, __neg));
213 else if (_M_match_token(_ScannerT::_S_token_opt))
217 auto __end = _M_nfa->_M_insert_dummy();
218 _StateSeqT __r(*_M_nfa,
219 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
220 __e._M_start, __neg));
221 __e._M_append(__end);
222 __r._M_append(__end);
225 else if (_M_match_token(_ScannerT::_S_token_interval_begin))
227 if (_M_stack.empty())
229 "Nothing to repeat before a quantifier.");
230 if (!_M_match_token(_ScannerT::_S_token_dup_count))
232 "Unexpected token in brace expression.");
233 _StateSeqT __r(_M_pop());
234 _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy());
235 long __min_rep = _M_cur_int_value(10);
240 if (_M_match_token(_ScannerT::_S_token_comma))
241 if (_M_match_token(_ScannerT::_S_token_dup_count))
242 __n = _M_cur_int_value(10) - __min_rep;
247 if (!_M_match_token(_ScannerT::_S_token_interval_end))
249 "Unexpected end of brace expression.");
251 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
253 for (
long __i = 0; __i < __min_rep; ++__i)
254 __e._M_append(__r._M_clone());
258 auto __tmp = __r._M_clone();
259 _StateSeqT __s(*_M_nfa,
260 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
261 __tmp._M_start, __neg));
262 __tmp._M_append(__s);
269 "Invalid range in brace expression.");
270 auto __end = _M_nfa->_M_insert_dummy();
275 for (
long __i = 0; __i < __n; ++__i)
277 auto __tmp = __r._M_clone();
278 auto __alt = _M_nfa->_M_insert_repeat(__tmp._M_start,
281 __e._M_append(_StateSeqT(*_M_nfa, __alt, __tmp._M_end));
283 __e._M_append(__end);
284 while (!__stack.
empty())
286 auto& __tmp = (*_M_nfa)[__stack.
top()];
288 std::swap(__tmp._M_next, __tmp._M_alt);
298 #define __INSERT_REGEX_MATCHER(__func, ...)\ 300 if (!(_M_flags & regex_constants::icase))\ 301 if (!(_M_flags & regex_constants::collate))\ 302 __func<false, false>(__VA_ARGS__);\ 304 __func<false, true>(__VA_ARGS__);\ 306 if (!(_M_flags & regex_constants::collate))\ 307 __func<true, false>(__VA_ARGS__);\ 309 __func<true, true>(__VA_ARGS__);\ 312 template<
typename _TraitsT>
314 _Compiler<_TraitsT>::
317 if (_M_match_token(_ScannerT::_S_token_anychar))
320 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_posix);
322 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_ecma);
324 else if (_M_try_char())
325 __INSERT_REGEX_MATCHER(_M_insert_char_matcher);
326 else if (_M_match_token(_ScannerT::_S_token_backref))
327 _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->
328 _M_insert_backref(_M_cur_int_value(10))));
329 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
330 __INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
331 else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin))
333 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_dummy());
334 this->_M_disjunction();
335 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
337 "Parenthesis is not closed.");
338 __r._M_append(_M_pop());
341 else if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
343 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_subexpr_begin());
344 this->_M_disjunction();
345 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
347 "Parenthesis is not closed.");
348 __r._M_append(_M_pop());
349 __r._M_append(_M_nfa->_M_insert_subexpr_end());
352 else if (!_M_bracket_expression())
357 template<
typename _TraitsT>
359 _Compiler<_TraitsT>::
360 _M_bracket_expression()
363 _M_match_token(_ScannerT::_S_token_bracket_neg_begin);
364 if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin)))
366 __INSERT_REGEX_MATCHER(_M_insert_bracket_matcher, __neg);
369 #undef __INSERT_REGEX_MATCHER 371 template<
typename _TraitsT>
372 template<
bool __icase,
bool __collate>
374 _Compiler<_TraitsT>::
375 _M_insert_any_matcher_ecma()
377 _M_stack.push(_StateSeqT(*_M_nfa,
378 _M_nfa->_M_insert_matcher
379 (_AnyMatcher<_TraitsT, true, __icase, __collate>
383 template<
typename _TraitsT>
384 template<
bool __icase,
bool __collate>
386 _Compiler<_TraitsT>::
387 _M_insert_any_matcher_posix()
389 _M_stack.push(_StateSeqT(*_M_nfa,
390 _M_nfa->_M_insert_matcher
391 (_AnyMatcher<_TraitsT, false, __icase, __collate>
395 template<
typename _TraitsT>
396 template<
bool __icase,
bool __collate>
398 _Compiler<_TraitsT>::
399 _M_insert_char_matcher()
401 _M_stack.push(_StateSeqT(*_M_nfa,
402 _M_nfa->_M_insert_matcher
403 (_CharMatcher<_TraitsT, __icase, __collate>
404 (_M_value[0], _M_traits))));
407 template<
typename _TraitsT>
408 template<
bool __icase,
bool __collate>
410 _Compiler<_TraitsT>::
411 _M_insert_character_class_matcher()
413 __glibcxx_assert(_M_value.size() == 1);
414 _BracketMatcher<__icase, __collate> __matcher
415 (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits);
416 __matcher._M_add_character_class(_M_value,
false);
417 __matcher._M_ready();
418 _M_stack.push(_StateSeqT(*_M_nfa,
419 _M_nfa->_M_insert_matcher(std::move(__matcher))));
422 template<
typename _TraitsT>
423 template<
bool __icase,
bool __collate>
425 _Compiler<_TraitsT>::
426 _M_insert_bracket_matcher(
bool __neg)
428 _BracketMatcher<__icase, __collate> __matcher(__neg, _M_traits);
429 _BracketState __last_char;
431 __last_char.set(_M_value[0]);
432 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
434 __last_char.set(
'-');
435 while (_M_expression_term(__last_char, __matcher))
437 if (__last_char._M_is_char())
438 __matcher._M_add_char(__last_char.get());
439 __matcher._M_ready();
440 _M_stack.push(_StateSeqT(
442 _M_nfa->_M_insert_matcher(std::move(__matcher))));
445 template<
typename _TraitsT>
446 template<
bool __icase,
bool __collate>
448 _Compiler<_TraitsT>::
449 _M_expression_term(_BracketState& __last_char,
450 _BracketMatcher<__icase, __collate>& __matcher)
452 if (_M_match_token(_ScannerT::_S_token_bracket_end))
456 const auto __push_char = [&](_CharT __ch)
458 if (__last_char._M_is_char())
459 __matcher._M_add_char(__last_char.get());
460 __last_char.set(__ch);
463 const auto __push_class = [&]
465 if (__last_char._M_is_char())
466 __matcher._M_add_char(__last_char.get());
469 __last_char.reset(_BracketState::_Type::_Class);
472 if (_M_match_token(_ScannerT::_S_token_collsymbol))
474 auto __symbol = __matcher._M_add_collate_element(_M_value);
475 if (__symbol.size() == 1)
476 __push_char(__symbol[0]);
480 else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
483 __matcher._M_add_equivalence_class(_M_value);
485 else if (_M_match_token(_ScannerT::_S_token_char_class_name))
488 __matcher._M_add_character_class(_M_value,
false);
490 else if (_M_try_char())
491 __push_char(_M_value[0]);
502 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
504 if (_M_match_token(_ScannerT::_S_token_bracket_end))
510 else if (__last_char._M_is_class())
514 "Invalid start of range in bracket expression.");
516 else if (__last_char._M_is_char())
521 __matcher._M_make_range(__last_char.get(), _M_value[0]);
524 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
527 __matcher._M_make_range(__last_char.get(),
'-');
532 "Invalid end of range in bracket expression.");
543 "Invalid dash in bracket expression.");
545 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
548 __matcher._M_add_character_class(_M_value,
549 _M_ctype.is(_CtypeT::upper,
554 "Unexpected character in bracket expression.");
559 template<
typename _TraitsT>
561 _Compiler<_TraitsT>::
564 bool __is_char =
false;
565 if (_M_match_token(_ScannerT::_S_token_oct_num))
568 _M_value.assign(1, _M_cur_int_value(8));
570 else if (_M_match_token(_ScannerT::_S_token_hex_num))
573 _M_value.assign(1, _M_cur_int_value(16));
575 else if (_M_match_token(_ScannerT::_S_token_ord_char))
580 template<
typename _TraitsT>
582 _Compiler<_TraitsT>::
583 _M_match_token(_TokenT __token)
585 if (__token == _M_scanner._M_get_token())
587 _M_value = _M_scanner._M_get_value();
588 _M_scanner._M_advance();
594 template<
typename _TraitsT>
596 _Compiler<_TraitsT>::
597 _M_cur_int_value(
int __radix)
600 for (
typename _StringT::size_type __i = 0;
601 __i < _M_value.length(); ++__i)
602 __v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
606 template<
typename _TraitsT,
bool __icase,
bool __collate>
608 _BracketMatcher<_TraitsT, __icase, __collate>::
613 if (std::binary_search(_M_char_set.begin(), _M_char_set.end(),
614 _M_translator._M_translate(__ch)))
616 auto __s = _M_translator._M_transform(__ch);
617 for (
auto& __it : _M_range_set)
618 if (_M_translator._M_match_range(__it.first, __it.second, __s))
620 if (_M_traits.isctype(__ch, _M_class_set))
622 if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(),
623 _M_traits.transform_primary(&__ch, &__ch+1))
624 != _M_equiv_set.end())
626 for (
auto& __it : _M_neg_class_set)
627 if (!_M_traits.isctype(__ch, __it))
630 }() ^ _M_is_non_matching;
634 _GLIBCXX_END_NAMESPACE_VERSION
shared_ptr< _Tp > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
void push(const value_type &__x)
Add data to the top of the stack.
A standard container giving FILO behavior.
_GLIBCXX17_INLINE constexpr syntax_option_type ECMAScript
constexpr error_type error_brace(_S_error_brace)
constexpr error_type error_badrepeat(_S_error_badrepeat)
const _Facet & use_facet(const locale &__loc)
Return a facet.use_facet looks for and returns a reference to a facet of type Facet where Facet is th...
void pop()
Removes first element.
ISO C++ entities toplevel namespace is std.
_GLIBCXX17_INLINE constexpr syntax_option_type extended
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
constexpr error_type error_range(_S_error_range)
_GLIBCXX17_INLINE constexpr syntax_option_type awk
constexpr error_type error_badbrace(_S_error_badbrace)
_GLIBCXX17_INLINE constexpr syntax_option_type grep
_GLIBCXX17_INLINE constexpr syntax_option_type egrep
constexpr error_type error_paren(_S_error_paren)
constexpr error_type error_brack(_S_error_brack)
_GLIBCXX17_INLINE constexpr syntax_option_type basic