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_DEBUG_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 auto __tmp = _M_pop();
167 __tmp._M_append(_M_nfa->_M_insert_accept());
171 _M_nfa->_M_insert_lookahead(__tmp._M_start, __neg)));
178 template<
typename _TraitsT>
180 _Compiler<_TraitsT>::
184 auto __init = [
this, &__neg]()
186 if (_M_stack.
empty())
188 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
190 if (_M_match_token(_ScannerT::_S_token_closure0))
194 _StateSeqT __r(*_M_nfa,
195 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
196 __e._M_start, __neg));
200 else if (_M_match_token(_ScannerT::_S_token_closure1))
204 __e._M_append(_M_nfa->_M_insert_repeat(_S_invalid_state_id,
205 __e._M_start, __neg));
208 else if (_M_match_token(_ScannerT::_S_token_opt))
212 auto __end = _M_nfa->_M_insert_dummy();
213 _StateSeqT __r(*_M_nfa,
214 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
215 __e._M_start, __neg));
216 __e._M_append(__end);
217 __r._M_append(__end);
220 else if (_M_match_token(_ScannerT::_S_token_interval_begin))
222 if (_M_stack.
empty())
224 if (!_M_match_token(_ScannerT::_S_token_dup_count))
226 _StateSeqT __r(_M_pop());
227 _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy());
228 long __min_rep = _M_cur_int_value(10);
233 if (_M_match_token(_ScannerT::_S_token_comma))
234 if (_M_match_token(_ScannerT::_S_token_dup_count))
235 __n = _M_cur_int_value(10) - __min_rep;
240 if (!_M_match_token(_ScannerT::_S_token_interval_end))
243 __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
245 for (
long __i = 0; __i < __min_rep; ++__i)
246 __e._M_append(__r._M_clone());
250 auto __tmp = __r._M_clone();
251 _StateSeqT __s(*_M_nfa,
252 _M_nfa->_M_insert_repeat(_S_invalid_state_id,
253 __tmp._M_start, __neg));
254 __tmp._M_append(__s);
261 auto __end = _M_nfa->_M_insert_dummy();
266 for (
long __i = 0; __i < __n; ++__i)
268 auto __tmp = __r._M_clone();
269 auto __alt = _M_nfa->_M_insert_repeat(__tmp._M_start,
272 __e._M_append(_StateSeqT(*_M_nfa, __alt, __tmp._M_end));
274 __e._M_append(__end);
275 while (!__stack.
empty())
277 auto& __tmp = (*_M_nfa)[__stack.
top()];
279 std::swap(__tmp._M_next, __tmp._M_alt);
289 #define __INSERT_REGEX_MATCHER(__func, args...)\ 291 if (!(_M_flags & regex_constants::icase))\ 292 if (!(_M_flags & regex_constants::collate))\ 293 __func<false, false>(args);\ 295 __func<false, true>(args);\ 297 if (!(_M_flags & regex_constants::collate))\ 298 __func<true, false>(args);\ 300 __func<true, true>(args);\ 303 template<
typename _TraitsT>
305 _Compiler<_TraitsT>::
308 if (_M_match_token(_ScannerT::_S_token_anychar))
311 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_posix);
313 __INSERT_REGEX_MATCHER(_M_insert_any_matcher_ecma);
315 else if (_M_try_char())
316 __INSERT_REGEX_MATCHER(_M_insert_char_matcher);
317 else if (_M_match_token(_ScannerT::_S_token_backref))
318 _M_stack.
push(_StateSeqT(*_M_nfa, _M_nfa->
319 _M_insert_backref(_M_cur_int_value(10))));
320 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
321 __INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
322 else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin))
324 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_dummy());
325 this->_M_disjunction();
326 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
328 __r._M_append(_M_pop());
331 else if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
333 _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_subexpr_begin());
334 this->_M_disjunction();
335 if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
337 __r._M_append(_M_pop());
338 __r._M_append(_M_nfa->_M_insert_subexpr_end());
341 else if (!_M_bracket_expression())
346 template<
typename _TraitsT>
348 _Compiler<_TraitsT>::
349 _M_bracket_expression()
352 _M_match_token(_ScannerT::_S_token_bracket_neg_begin);
353 if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin)))
355 __INSERT_REGEX_MATCHER(_M_insert_bracket_matcher, __neg);
358 #undef __INSERT_REGEX_MATCHER 360 template<
typename _TraitsT>
361 template<
bool __icase,
bool __collate>
363 _Compiler<_TraitsT>::
364 _M_insert_any_matcher_ecma()
366 _M_stack.
push(_StateSeqT(*_M_nfa,
367 _M_nfa->_M_insert_matcher
368 (_AnyMatcher<_TraitsT, true, __icase, __collate>
372 template<
typename _TraitsT>
373 template<
bool __icase,
bool __collate>
375 _Compiler<_TraitsT>::
376 _M_insert_any_matcher_posix()
378 _M_stack.
push(_StateSeqT(*_M_nfa,
379 _M_nfa->_M_insert_matcher
380 (_AnyMatcher<_TraitsT, false, __icase, __collate>
384 template<
typename _TraitsT>
385 template<
bool __icase,
bool __collate>
387 _Compiler<_TraitsT>::
388 _M_insert_char_matcher()
390 _M_stack.
push(_StateSeqT(*_M_nfa,
391 _M_nfa->_M_insert_matcher
392 (_CharMatcher<_TraitsT, __icase, __collate>
393 (_M_value[0], _M_traits))));
396 template<
typename _TraitsT>
397 template<
bool __icase,
bool __collate>
399 _Compiler<_TraitsT>::
400 _M_insert_character_class_matcher()
402 _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1);
403 _BracketMatcher<_TraitsT, __icase, __collate> __matcher
404 (_M_ctype.
is(_CtypeT::upper, _M_value[0]), _M_traits);
405 __matcher._M_add_character_class(_M_value,
false);
406 __matcher._M_ready();
407 _M_stack.
push(_StateSeqT(*_M_nfa,
408 _M_nfa->_M_insert_matcher(std::move(__matcher))));
411 template<
typename _TraitsT>
412 template<
bool __icase,
bool __collate>
414 _Compiler<_TraitsT>::
415 _M_insert_bracket_matcher(
bool __neg)
417 _BracketMatcher<_TraitsT, __icase, __collate> __matcher(__neg, _M_traits);
418 pair<bool, _CharT> __last_char;
419 __last_char.first =
false;
423 __matcher._M_add_char(_M_value[0]);
424 __last_char.first =
true;
425 __last_char.second = _M_value[0];
427 while (_M_expression_term(__last_char, __matcher));
428 __matcher._M_ready();
429 _M_stack.
push(_StateSeqT(
431 _M_nfa->_M_insert_matcher(std::move(__matcher))));
434 template<
typename _TraitsT>
435 template<
bool __icase,
bool __collate>
437 _Compiler<_TraitsT>::
438 _M_expression_term(pair<bool, _CharT>& __last_char,
439 _BracketMatcher<_TraitsT, __icase, __collate>& __matcher)
441 if (_M_match_token(_ScannerT::_S_token_bracket_end))
444 if (_M_match_token(_ScannerT::_S_token_collsymbol))
446 auto __symbol = __matcher._M_add_collate_element(_M_value);
447 if (__symbol.size() == 1)
449 __last_char.first =
true;
450 __last_char.second = __symbol[0];
453 else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
454 __matcher._M_add_equivalence_class(_M_value);
455 else if (_M_match_token(_ScannerT::_S_token_char_class_name))
456 __matcher._M_add_character_class(_M_value,
false);
467 else if (_M_try_char())
469 if (!__last_char.first)
471 __matcher._M_add_char(_M_value[0]);
472 if (_M_value[0] ==
'-' 473 && !(_M_flags & regex_constants::ECMAScript))
475 if (_M_match_token(_ScannerT::_S_token_bracket_end))
479 __last_char.first =
true;
480 __last_char.second = _M_value[0];
484 if (_M_value[0] ==
'-')
488 __matcher._M_make_range(__last_char.second , _M_value[0]);
489 __last_char.first =
false;
493 if (_M_scanner._M_get_token()
494 != _ScannerT::_S_token_bracket_end)
496 __matcher._M_add_char(_M_value[0]);
501 __matcher._M_add_char(_M_value[0]);
502 __last_char.second = _M_value[0];
506 else if (_M_match_token(_ScannerT::_S_token_quoted_class))
507 __matcher._M_add_character_class(_M_value,
508 _M_ctype.
is(_CtypeT::upper,
516 template<
typename _TraitsT>
518 _Compiler<_TraitsT>::
521 bool __is_char =
false;
522 if (_M_match_token(_ScannerT::_S_token_oct_num))
525 _M_value.assign(1, _M_cur_int_value(8));
527 else if (_M_match_token(_ScannerT::_S_token_hex_num))
530 _M_value.assign(1, _M_cur_int_value(16));
532 else if (_M_match_token(_ScannerT::_S_token_ord_char))
537 template<
typename _TraitsT>
539 _Compiler<_TraitsT>::
540 _M_match_token(_TokenT token)
542 if (token == _M_scanner._M_get_token())
544 _M_value = _M_scanner._M_get_value();
545 _M_scanner._M_advance();
551 template<
typename _TraitsT>
553 _Compiler<_TraitsT>::
554 _M_cur_int_value(
int __radix)
557 for (
typename _StringT::size_type __i = 0;
558 __i < _M_value.length(); ++__i)
559 __v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
563 template<
typename _TraitsT,
bool __icase,
bool __collate>
565 _BracketMatcher<_TraitsT, __icase, __collate>::
569 _M_translator._M_translate(__ch));
572 auto __s = _M_translator._M_transform(__ch);
573 for (
auto& __it : _M_range_set)
574 if (__it.first <= __s && __s <= __it.second)
579 if (_M_traits.isctype(__ch, _M_class_set))
581 else if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(),
582 _M_traits.transform_primary(&__ch, &__ch+1))
583 != _M_equiv_set.end())
587 for (
auto& __it : _M_neg_class_set)
588 if (!_M_traits.isctype(__ch, __it))
595 if (_M_is_non_matching)
601 _GLIBCXX_END_NAMESPACE_VERSION
void push(const value_type &__x)
Add data to the top of the stack.
constexpr syntax_option_type grep
constexpr syntax_option_type egrep
void pop()
Removes first element.
constexpr error_type error_range(_S_error_range)
A standard container giving FILO behavior.
bool is(mask __m, char_type __c) const
Test char_type classification.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
constexpr syntax_option_type basic
constexpr error_type error_badrepeat(_S_error_badrepeat)
constexpr syntax_option_type awk
shared_ptr< _Tp > make_shared(_Args &&...__args)
Create an object that is owned by a shared_ptr.
bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__val, _Compare __comp)
Determines whether an element exists in a range.
constexpr syntax_option_type ECMAScript
constexpr error_type error_paren(_S_error_paren)
constexpr error_type error_brace(_S_error_brace)
constexpr error_type error_badbrace(_S_error_badbrace)
constexpr error_type error_brack(_S_error_brack)
constexpr syntax_option_type extended
ISO C++ entities toplevel namespace is std.
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...