1 // class template regex -*- C++ -*-
3 // Copyright (C) 2013 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
26 * @file bits/regex_executor.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{regex}
31 // TODO: convert comments to doxygen format.
33 namespace std
_GLIBCXX_VISIBILITY(default)
35 _GLIBCXX_BEGIN_NAMESPACE_VERSION
36 template<typename
, typename
>
42 template<typename
, typename
>
44 _GLIBCXX_END_NAMESPACE_VERSION
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
51 * @addtogroup regex-detail
55 template<typename _BiIter
, typename _Alloc
,
56 typename _CharT
, typename _TraitsT
>
60 typedef match_results
<_BiIter
, _Alloc
> _ResultsT
;
61 typedef std::vector
<sub_match
<_BiIter
>, _Alloc
> _ResultsVec
;
62 typedef regex_constants::match_flag_type _FlagT
;
68 // Set matched when string exactly match the pattern.
72 // Set matched when some prefix of the string matches the pattern.
74 _M_search_from_first() = 0;
77 typedef typename _NFA
<_CharT
, _TraitsT
>::_SizeT _SizeT
;
78 _Executor(_BiIter __begin
,
83 : _M_current(__begin
), _M_end(__end
), _M_results(__results
),
87 _M_results
.resize(__size
);
88 for (auto __i
= 0; __i
< __size
; __i
++)
89 _M_results
[__i
].matched
= false;
94 _ResultsVec
& _M_results
;
98 // A _DFSExecutor perform a DFS on given NFA and input string. At the very
99 // beginning the executor stands in the start state, then it try every
100 // possible state transition in current state recursively. Some state
101 // transitions consume input string, say, a single-char-matcher or a
102 // back-reference matcher; some not, like assertion or other anchor nodes.
103 // When the input is exhausted and the current state is an accepting state,
104 // the whole executor return true.
106 // TODO: This approach is exponentially slow for certain input.
107 // Try to compile the NFA to a DFA.
109 // Time complexity: exponential
110 // Space complexity: O(__end - __begin)
111 template<typename _BiIter
, typename _Alloc
,
112 typename _CharT
, typename _TraitsT
>
114 : public _Executor
<_BiIter
, _Alloc
, _CharT
, _TraitsT
>
117 typedef _Executor
<_BiIter
, _Alloc
, _CharT
, _TraitsT
> _BaseT
;
118 typedef _NFA
<_CharT
, _TraitsT
> _RegexT
;
119 typedef typename
_BaseT::_ResultsT _ResultsT
;
120 typedef typename
_BaseT::_ResultsVec _ResultsVec
;
121 typedef regex_constants::match_flag_type _FlagT
;
123 _DFSExecutor(_BiIter __begin
,
125 _ResultsT
& __results
,
126 const _RegexT
& __nfa
,
127 const _TraitsT
& __traits
,
129 : _BaseT(__begin
, __end
, __results
, __flags
, __nfa
._M_sub_count()),
130 _M_traits(__traits
), _M_nfa(__nfa
), _M_results_ret(this->_M_results
)
135 { _M_dfs
<true>(_M_nfa
._M_start()); }
138 _M_search_from_first()
139 { _M_dfs
<false>(_M_nfa
._M_start()); }
142 template<bool __match_mode
>
144 _M_dfs(_StateIdT __i
);
146 _ResultsVec _M_results_ret
;
147 const _TraitsT
& _M_traits
;
148 const _RegexT
& _M_nfa
;
151 // Like the DFS approach, it try every possible state transition; Unlike DFS,
152 // it uses a queue instead of a stack to store matching states. It's a BFS
155 // Russ Cox's article(http://swtch.com/~rsc/regexp/regexp1.html) explained
156 // this algorithm clearly.
158 // Every entry of _M_covered saves the solution(grouping status) for every
159 // matching head. When states transit, solutions will be compared and
160 // deduplicated(based on which greedy mode we have).
162 // Time complexity: O((__end - __begin) * _M_nfa.size())
163 // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
164 template<typename _BiIter
, typename _Alloc
,
165 typename _CharT
, typename _TraitsT
>
167 : public _Executor
<_BiIter
, _Alloc
, _CharT
, _TraitsT
>
170 typedef _Executor
<_BiIter
, _Alloc
, _CharT
, _TraitsT
> _BaseT
;
171 typedef _NFA
<_CharT
, _TraitsT
> _RegexT
;
172 typedef typename
_BaseT::_ResultsT _ResultsT
;
173 typedef typename
_BaseT::_ResultsVec _ResultsVec
;
174 typedef std::unique_ptr
<_ResultsVec
> _ResultsPtr
;
175 typedef regex_constants::match_flag_type _FlagT
;
177 _BFSExecutor(_BiIter __begin
,
179 _ResultsT
& __results
,
180 const _RegexT
& __nfa
,
182 : _BaseT(__begin
, __end
, __results
, __flags
, __nfa
._M_sub_count()),
185 if (_M_nfa
._M_start() != _S_invalid_state_id
)
186 _M_covered
[_M_nfa
._M_start()] =
187 _ResultsPtr(new _ResultsVec(this->_M_results
));
193 { _M_main_loop
<true>(); }
196 _M_search_from_first()
197 { _M_main_loop
<false>(); }
200 template<bool __match_mode
>
211 _M_match_less_than(const _ResultsVec
& __u
, const _ResultsVec
& __v
) const;
214 _M_includes_some() const;
216 std::map
<_StateIdT
, _ResultsPtr
> _M_covered
;
217 const _RegexT
& _M_nfa
;
221 _GLIBCXX_END_NAMESPACE_VERSION
222 } // namespace __detail
225 #include <bits/regex_executor.tcc>