]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/regex_automaton.h
regex.h: Replace 8 spaces in indentation with a tab.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / regex_automaton.h
1 // class template regex -*- C++ -*-
2
3 // Copyright (C) 2013 Free Software Foundation, Inc.
4 //
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)
9 // any later version.
10
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.
15
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.
19
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/>.
24
25 /**
26 * @file bits/regex_automaton.h
27 * This is an internal header file, included by other library headers.
28 * Do not attempt to use it directly. @headername{regex}
29 */
30
31 namespace std _GLIBCXX_VISIBILITY(default)
32 {
33 namespace __detail
34 {
35 _GLIBCXX_BEGIN_NAMESPACE_VERSION
36
37 /**
38 * @defgroup regex-detail Base and Implementation Classes
39 * @ingroup regex
40 * @{
41 */
42
43 typedef int _StateIdT;
44 typedef std::set<_StateIdT> _StateSet;
45 static const _StateIdT _S_invalid_state_id = -1;
46
47 template<typename _CharT>
48 using _Matcher = std::function<bool (_CharT)>;
49
50 /// Operation codes that define the type of transitions within the base NFA
51 /// that represents the regular expression.
52 enum _Opcode
53 {
54 _S_opcode_unknown = 0,
55 _S_opcode_alternative = 1,
56 _S_opcode_backref = 2,
57 _S_opcode_subexpr_begin = 4,
58 _S_opcode_subexpr_end = 5,
59 _S_opcode_match = 100,
60 _S_opcode_accept = 255
61 };
62
63 template<typename _CharT, typename _TraitsT>
64 class _State
65 {
66 public:
67 typedef int _OpcodeT;
68 typedef _Matcher<_CharT> _MatcherT;
69
70 _OpcodeT _M_opcode; // type of outgoing transition
71 _StateIdT _M_next; // outgoing transition
72 union // Since they are mutual exclusive.
73 {
74 _StateIdT _M_alt; // for _S_opcode_alternative
75 unsigned int _M_subexpr; // for _S_opcode_subexpr_*
76 unsigned int _M_backref_index; // for _S_opcode_backref
77 };
78 _MatcherT _M_matches; // for _S_opcode_match
79
80 explicit _State(_OpcodeT __opcode)
81 : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
82 { }
83
84 _State(const _MatcherT& __m)
85 : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id),
86 _M_matches(__m)
87 { }
88
89 _State(_OpcodeT __opcode, unsigned __index)
90 : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
91 {
92 if (__opcode == _S_opcode_subexpr_begin
93 || __opcode == _S_opcode_subexpr_end)
94 _M_subexpr = __index;
95 else if (__opcode == _S_opcode_backref)
96 _M_backref_index = __index;
97 }
98
99 _State(_StateIdT __next, _StateIdT __alt)
100 : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
101 { }
102
103 #ifdef _GLIBCXX_DEBUG
104 std::ostream&
105 _M_print(std::ostream& ostr) const;
106
107 // Prints graphviz dot commands for state.
108 std::ostream&
109 _M_dot(std::ostream& __ostr, _StateIdT __id) const;
110 #endif
111 };
112
113 /// Base class for, um, automata. Could be an NFA or a DFA. Your choice.
114 template<typename _CharT, typename _TraitsT>
115 class _Automaton
116 {
117 public:
118 typedef unsigned int _SizeT;
119
120 public:
121 virtual _SizeT
122 _M_sub_count() const = 0;
123
124 #ifdef _GLIBCXX_DEBUG
125 virtual std::ostream&
126 _M_dot(std::ostream& __ostr) const = 0;
127 #endif
128 };
129
130 template<typename _CharT, typename _TraitsT>
131 class _NFA
132 : public _Automaton<_CharT, _TraitsT>,
133 public std::vector<_State<_CharT, _TraitsT>>
134 {
135 public:
136 typedef _State<_CharT, _TraitsT> _StateT;
137 typedef const _Matcher<_CharT>& _MatcherT;
138 typedef unsigned int _SizeT;
139 typedef regex_constants::syntax_option_type _FlagT;
140
141 _NFA(_FlagT __f)
142 : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
143 _M_has_backref(false)
144 { }
145
146 _FlagT
147 _M_options() const
148 { return _M_flags; }
149
150 _StateIdT
151 _M_start() const
152 { return _M_start_state; }
153
154 const _StateSet&
155 _M_final_states() const
156 { return _M_accepting_states; }
157
158 _SizeT
159 _M_sub_count() const
160 { return _M_subexpr_count; }
161
162 _StateIdT
163 _M_insert_accept()
164 {
165 this->push_back(_StateT(_S_opcode_accept));
166 _M_accepting_states.insert(this->size()-1);
167 return this->size()-1;
168 }
169
170 _StateIdT
171 _M_insert_alt(_StateIdT __next, _StateIdT __alt)
172 {
173 this->push_back(_StateT(__next, __alt));
174 return this->size()-1;
175 }
176
177 _StateIdT
178 _M_insert_matcher(_MatcherT __m)
179 {
180 this->push_back(_StateT(__m));
181 return this->size()-1;
182 }
183
184 _StateIdT
185 _M_insert_subexpr_begin()
186 {
187 auto __id = _M_subexpr_count++;
188 _M_paren_stack.push_back(__id);
189 this->push_back(_StateT(_S_opcode_subexpr_begin, __id));
190 return this->size()-1;
191 }
192
193 _StateIdT
194 _M_insert_subexpr_end()
195 {
196 this->push_back(_StateT(_S_opcode_subexpr_end, _M_paren_stack.back()));
197 _M_paren_stack.pop_back();
198 return this->size()-1;
199 }
200
201 _StateIdT
202 _M_insert_backref(unsigned int __index);
203
204 #ifdef _GLIBCXX_DEBUG
205 std::ostream&
206 _M_dot(std::ostream& __ostr) const;
207 #endif
208
209 _FlagT _M_flags;
210 _StateIdT _M_start_state;
211 _StateSet _M_accepting_states;
212 _SizeT _M_subexpr_count;
213 bool _M_has_backref;
214 std::vector<unsigned int> _M_paren_stack;
215 };
216
217 /// Describes a sequence of one or more %_State, its current start
218 /// and end(s). This structure contains fragments of an NFA during
219 /// construction.
220 template<typename _CharT, typename _TraitsT>
221 class _StateSeq
222 {
223 public:
224 typedef _NFA<_CharT, _TraitsT> _RegexT;
225 public:
226 // Constructs a single-node sequence
227 _StateSeq(_RegexT& __ss, _StateIdT __s,
228 _StateIdT __e = _S_invalid_state_id)
229 : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
230 { }
231 // Constructs a split sequence from two other sequencces
232 _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
233 : _M_nfa(__e1._M_nfa),
234 _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
235 _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
236 { }
237
238 // Constructs a split sequence from a single sequence
239 _StateSeq(const _StateSeq& __e, _StateIdT __id)
240 : _M_nfa(__e._M_nfa),
241 _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
242 _M_end1(__id), _M_end2(__e._M_end1)
243 { }
244
245 // Constructs a copy of a %_StateSeq
246 _StateSeq(const _StateSeq& __rhs)
247 : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
248 _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
249 { }
250
251 _StateSeq& operator=(const _StateSeq& __rhs);
252
253 _StateIdT
254 _M_front() const
255 { return _M_start; }
256
257 // Extends a sequence by one.
258 void
259 _M_push_back(_StateIdT __id);
260
261 // Extends and maybe joins a sequence.
262 void
263 _M_append(_StateIdT __id);
264
265 void
266 _M_append(_StateSeq& __rhs);
267
268 // Clones an entire sequence.
269 _StateIdT
270 _M_clone();
271
272 private:
273 _RegexT& _M_nfa;
274 _StateIdT _M_start;
275 _StateIdT _M_end1;
276 _StateIdT _M_end2;
277 };
278
279 //@} regex-detail
280 _GLIBCXX_END_NAMESPACE_VERSION
281 } // namespace __detail
282 } // namespace std
283
284 #include <bits/regex_automaton.tcc>