56 namespace std _GLIBCXX_VISIBILITY(default)
60 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 template<
typename _TraitsT>
64 _Compiler(_IterT __b, _IterT __e,
65 const typename _TraitsT::locale_type& __loc, _FlagT __flags)
68 | regex_constants::
basic 70 | regex_constants::
grep 71 | regex_constants::
egrep 72 | regex_constants::
awk))
75 _M_scanner(__b, __e, _M_flags, __loc),
77 _M_traits(_M_nfa->_M_traits),
80 _StateSeqT __r(*_M_nfa, _M_nfa->_M_start());
81 __r._M_append(_M_nfa->_M_insert_subexpr_begin());
82 this->_M_disjunction();
83 if (!_M_match_token(_ScannerT::_S_token_eof))
85 __r._M_append(_M_pop());
86 __glibcxx_assert(_M_stack.
empty());
87 __r._M_append(_M_nfa->_M_insert_subexpr_end());
88 __r._M_append(_M_nfa->_M_insert_accept());
89 _M_nfa->_M_eliminate_dummy();
92 template<
typename _TraitsT>
97 this->_M_alternative();
98 while (_M_match_token(_ScannerT::_S_token_or))
100 _StateSeqT __alt1 = _M_pop();
101 this->_M_alternative();
102 _StateSeqT __alt2 = _M_pop();
103 auto __end = _M_nfa->_M_insert_dummy();
104 __alt1._M_append(__end);
105 __alt2._M_append(__end);
109 _M_stack.
push(_StateSeqT(*_M_nfa,
110 _M_nfa->_M_insert_alt(
111 __alt2._M_start, __alt1._M_start,
false),
116 template<
typename _TraitsT>
118 _Compiler<_TraitsT>::
123 _StateSeqT __re = _M_pop();
124 this->_M_alternative();
125 __re._M_append(_M_pop());
129 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_dummy()));
132 template<
typename _TraitsT>
134 _Compiler<_TraitsT>::
137 if (this->_M_assertion())
141 while (this->_M_quantifier());
147 template<
typename _TraitsT>
149 _Compiler<_TraitsT>::
152 if (_M_match_token(_ScannerT::_S_token_line_begin))
153 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_begin()));
154 else if (_M_match_token(_ScannerT::_S_token_line_end))
155 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_end()));
156 else if (_M_match_token(_ScannerT::_S_token_word_bound))
158 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->
159 _M_insert_word_bound(_M_value[0] ==
'n')));
160 else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin))
162 auto __neg = _M_value[0] ==
'n';
163 this->_M_disjunction();
164 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
166 "Parenthesis is not closed.");
167 auto __tmp = _M_pop();
168 __tmp._M_append(_M_nfa->_M_insert_accept());
172 _M_nfa->_M_insert_lookahead(__tmp._M_start, __neg)));
179 template<
typename _TraitsT>
181 _Compiler<_TraitsT>::
185 auto __init = [
this, &__neg]()
187 if (_M_stack.
empty())
189 "Nothing to repeat before a quantifier.");
190 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
192 if (_M_match_token(_ScannerT::_S_token_closure0))
196 _StateSeqT __r(*_M_nfa,
197 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
198 __e._M_start, __neg));
202 else if (_M_match_token(_ScannerT::_S_token_closure1))
206 __e._M_append(_M_nfa->_M_insert_repeat(_S_invalid_state_id,
207 __e._M_start, __neg));
210 else if (_M_match_token(_ScannerT::_S_token_opt))
214 auto __end = _M_nfa->_M_insert_dummy();
215 _StateSeqT __r(*_M_nfa,
216 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
217 __e._M_start, __neg));
218 __e._M_append(__end);
219 __r._M_append(__end);
222 else if (_M_match_token(_ScannerT::_S_token_interval_begin))
224 if (_M_stack.
empty())
226 "Nothing to repeat before a quantifier.");
227 if (!_M_match_token(_ScannerT::_S_token_dup_count))
229 "Unexpected token in brace expression.");
230 _StateSeqT __r(_M_pop());
231 _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy());
232 long __min_rep = _M_cur_int_value(10);
237 if (_M_match_token(_ScannerT::_S_token_comma))
238 if (_M_match_token(_ScannerT::_S_token_dup_count))
239 __n = _M_cur_int_value(10) - __min_rep;
244 if (!_M_match_token(_ScannerT::_S_token_interval_end))
246 "Unexpected end of brace expression.");
248 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
250 for (
long __i = 0; __i < __min_rep; ++__i)
251 __e._M_append(__r._M_clone());
255 auto __tmp = __r._M_clone();
256 _StateSeqT __s(*_M_nfa,
257 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
258 __tmp._M_start, __neg));
259 __tmp._M_append(__s);
266 "Invalid range in brace expression.");
267 auto __end = _M_nfa->_M_insert_dummy();
272 for (
long __i = 0; __i < __n; ++__i)
274 auto __tmp = __r._M_clone();
275 auto __alt = _M_nfa->_M_insert_repeat(__tmp._M_start,
278 __e._M_append(_StateSeqT(*_M_nfa, __alt, __tmp._M_end));
280 __e._M_append(__end);
281 while (!__stack.
empty())
283 auto& __tmp = (*_M_nfa)[__stack.
top()];
285 std::swap(__tmp._M_next, __tmp._M_alt);
295 #define __INSERT_REGEX_MATCHER(__func, args...)\ 297 if (!(_M_flags & regex_constants::icase))\ 298 if (!(_M_flags & regex_constants::collate))\ 299 __func<false, false>(args);\ 301 __func<false, true>(args);\ 303 if (!(_M_flags & regex_constants::collate))\ 304 __func<true, false>(args);\ 306 __func<true, true>(args);\ 309 template<
typename _TraitsT>
311 _Compiler<_TraitsT>::
314 if (_M_match_token(_ScannerT::_S_token_anychar))
317 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_posix);
319 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_ecma);
321 else if (_M_try_char())
322 __INSERT_REGEX_MATCHER(_M_insert_char_matcher);
323 else if (_M_match_token(_ScannerT::_S_token_backref))
324 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->
325 _M_insert_backref(_M_cur_int_value(10))));
326 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
327 __INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
328 else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin))
330 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_dummy());
331 this->_M_disjunction();
332 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
334 "Parenthesis is not closed.");
335 __r._M_append(_M_pop());
338 else if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
340 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_subexpr_begin());
341 this->_M_disjunction();
342 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
344 "Parenthesis is not closed.");
345 __r._M_append(_M_pop());
346 __r._M_append(_M_nfa->_M_insert_subexpr_end());
349 else if (!_M_bracket_expression())
354 template<
typename _TraitsT>
356 _Compiler<_TraitsT>::
357 _M_bracket_expression()
360 _M_match_token(_ScannerT::_S_token_bracket_neg_begin);
361 if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin)))
363 __INSERT_REGEX_MATCHER(_M_insert_bracket_matcher, __neg);
366 #undef __INSERT_REGEX_MATCHER 368 template<
typename _TraitsT>
369 template<
bool __icase,
bool __collate>
371 _Compiler<_TraitsT>::
372 _M_insert_any_matcher_ecma()
374 _M_stack.
push(_StateSeqT(*_M_nfa,
375 _M_nfa->_M_insert_matcher
376 (_AnyMatcher<_TraitsT, true, __icase, __collate>
380 template<
typename _TraitsT>
381 template<
bool __icase,
bool __collate>
383 _Compiler<_TraitsT>::
384 _M_insert_any_matcher_posix()
386 _M_stack.
push(_StateSeqT(*_M_nfa,
387 _M_nfa->_M_insert_matcher
388 (_AnyMatcher<_TraitsT, false, __icase, __collate>
392 template<
typename _TraitsT>
393 template<
bool __icase,
bool __collate>
395 _Compiler<_TraitsT>::
396 _M_insert_char_matcher()
398 _M_stack.
push(_StateSeqT(*_M_nfa,
399 _M_nfa->_M_insert_matcher
400 (_CharMatcher<_TraitsT, __icase, __collate>
401 (_M_value[0], _M_traits))));
404 template<
typename _TraitsT>
405 template<
bool __icase,
bool __collate>
407 _Compiler<_TraitsT>::
408 _M_insert_character_class_matcher()
410 __glibcxx_assert(_M_value.size() == 1);
411 _BracketMatcher<_TraitsT, __icase, __collate> __matcher
412 (_M_ctype.
is(_CtypeT::upper, _M_value[0]), _M_traits);
413 __matcher._M_add_character_class(_M_value,
false);
414 __matcher._M_ready();
415 _M_stack.
push(_StateSeqT(*_M_nfa,
416 _M_nfa->_M_insert_matcher(std::move(__matcher))));
419 template<
typename _TraitsT>
420 template<
bool __icase,
bool __collate>
422 _Compiler<_TraitsT>::
423 _M_insert_bracket_matcher(
bool __neg)
425 _BracketMatcher<_TraitsT, __icase, __collate> __matcher(__neg, _M_traits);
426 pair<bool, _CharT> __last_char;
427 __last_char.first =
false;
432 __last_char.first =
true;
433 __last_char.second = _M_value[0];
435 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
437 __last_char.first =
true;
438 __last_char.second =
'-';
441 while (_M_expression_term(__last_char, __matcher));
442 if (__last_char.first)
443 __matcher._M_add_char(__last_char.second);
444 __matcher._M_ready();
445 _M_stack.
push(_StateSeqT(
447 _M_nfa->_M_insert_matcher(std::move(__matcher))));
450 template<
typename _TraitsT>
451 template<
bool __icase,
bool __collate>
453 _Compiler<_TraitsT>::
454 _M_expression_term(pair<bool, _CharT>& __last_char,
455 _BracketMatcher<_TraitsT, __icase, __collate>& __matcher)
457 if (_M_match_token(_ScannerT::_S_token_bracket_end))
460 const auto __push_char = [&](_CharT __ch)
462 if (__last_char.first)
463 __matcher._M_add_char(__last_char.second);
465 __last_char.first =
true;
466 __last_char.second = __ch;
468 const auto __flush = [&]
470 if (__last_char.first)
472 __matcher._M_add_char(__last_char.second);
473 __last_char.first =
false;
477 if (_M_match_token(_ScannerT::_S_token_collsymbol))
479 auto __symbol = __matcher._M_add_collate_element(_M_value);
480 if (__symbol.size() == 1)
481 __push_char(__symbol[0]);
485 else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
488 __matcher._M_add_equivalence_class(_M_value);
490 else if (_M_match_token(_ScannerT::_S_token_char_class_name))
493 __matcher._M_add_character_class(_M_value,
false);
495 else if (_M_try_char())
496 __push_char(_M_value[0]);
507 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
509 if (!__last_char.first)
511 if (!(_M_flags & regex_constants::ECMAScript))
513 if (_M_match_token(_ScannerT::_S_token_bracket_end))
520 "Unexpected dash in bracket expression. For POSIX syntax, " 521 "a dash is not treated literally only when it is at " 522 "beginning or end.");
530 __matcher._M_make_range(__last_char.second, _M_value[0]);
531 __last_char.first =
false;
533 else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
535 __matcher._M_make_range(__last_char.second,
'-');
536 __last_char.first =
false;
540 if (_M_scanner._M_get_token()
541 != _ScannerT::_S_token_bracket_end)
544 "Character is expected after a dash.");
549 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
552 __matcher._M_add_character_class(_M_value,
553 _M_ctype.
is(_CtypeT::upper,
558 "Unexpected character in bracket expression.");
563 template<
typename _TraitsT>
565 _Compiler<_TraitsT>::
568 bool __is_char =
false;
569 if (_M_match_token(_ScannerT::_S_token_oct_num))
572 _M_value.assign(1, _M_cur_int_value(8));
574 else if (_M_match_token(_ScannerT::_S_token_hex_num))
577 _M_value.assign(1, _M_cur_int_value(16));
579 else if (_M_match_token(_ScannerT::_S_token_ord_char))
584 template<
typename _TraitsT>
586 _Compiler<_TraitsT>::
587 _M_match_token(_TokenT token)
589 if (token == _M_scanner._M_get_token())
591 _M_value = _M_scanner._M_get_value();
592 _M_scanner._M_advance();
598 template<
typename _TraitsT>
600 _Compiler<_TraitsT>::
601 _M_cur_int_value(
int __radix)
604 for (
typename _StringT::size_type __i = 0;
605 __i < _M_value.length(); ++__i)
606 __v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
610 template<
typename _TraitsT,
bool __icase,
bool __collate>
612 _BracketMatcher<_TraitsT, __icase, __collate>::
617 if (std::binary_search(_M_char_set.begin(), _M_char_set.end(),
618 _M_translator._M_translate(__ch)))
620 auto __s = _M_translator._M_transform(__ch);
621 for (
auto& __it : _M_range_set)
622 if (_M_translator._M_match_range(__it.first, __it.second, __s))
624 if (_M_traits.isctype(__ch, _M_class_set))
626 if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(),
627 _M_traits.transform_primary(&__ch, &__ch+1))
628 != _M_equiv_set.end())
630 for (
auto& __it : _M_neg_class_set)
631 if (!_M_traits.isctype(__ch, __it))
634 }() ^ _M_is_non_matching;
637 _GLIBCXX_END_NAMESPACE_VERSION
constexpr error_type error_brack(_S_error_brack)
void pop()
Removes first element.
constexpr error_type error_paren(_S_error_paren)
void push(const value_type &__x)
Add data to the top of the stack.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
_GLIBCXX17_INLINE constexpr syntax_option_type egrep
_GLIBCXX17_INLINE constexpr syntax_option_type grep
_GLIBCXX17_INLINE constexpr syntax_option_type ECMAScript
_GLIBCXX17_INLINE constexpr syntax_option_type extended
shared_ptr< _Tp > make_shared(_Args &&...__args)
Create an object that is owned by a shared_ptr.
A standard container giving FILO behavior.
bool is(mask __m, char_type __c) const
Test char_type classification.
ISO C++ entities toplevel namespace is std.
_GLIBCXX17_INLINE constexpr syntax_option_type awk
constexpr error_type error_badrepeat(_S_error_badrepeat)
_GLIBCXX17_INLINE constexpr syntax_option_type basic
constexpr error_type error_range(_S_error_range)
constexpr error_type error_brace(_S_error_brace)
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...
constexpr error_type error_badbrace(_S_error_badbrace)