1 // class template regex -*- C++ -*-
3 // Copyright (C) 2010 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_grep_matcher.tcc
31 _GLIBCXX_BEGIN_NAMESPACE(std)
36 // A stack of states used in evaluating the NFA.
37 typedef std::stack<std::__regex::_StateIdT,
38 std::vector<std::__regex::_StateIdT>
41 // Obtains the next state set given the current state set __s and the current
43 inline std::__regex::_StateSet
44 __move(const std::__regex::_PatternCursor& __p,
45 const std::__regex::_Nfa& __nfa,
46 const std::__regex::_StateSet& __s)
48 std::__regex::_StateSet __m;
49 for (std::__regex::_StateSet::const_iterator __i = __s.begin();
50 __i != __s.end(); ++__i)
52 if (*__i == std::__regex::_S_invalid_state_id)
55 const std::__regex::_State& __state = __nfa[*__i];
56 if (__state._M_opcode == std::__regex::_S_opcode_match
57 && __state._M_matches(__p))
58 __m.insert(__state._M_next);
63 // returns true if (__s intersect __t) is not empty
65 __includes_some(const std::__regex::_StateSet& __s,
66 const std::__regex::_StateSet& __t)
68 if (__s.size() > 0 && __t.size() > 0)
70 std::__regex::_StateSet::const_iterator __first = __s.begin();
71 std::__regex::_StateSet::const_iterator __second = __t.begin();
72 while (__first != __s.end() && __second != __t.end())
74 if (*__first < *__second)
76 else if (*__second < *__first)
85 // If an identified state __u is not already in the current state set __e,
86 // insert it and push it on the current state stack __s.
88 __add_visited_state(const std::__regex::_StateIdT __u,
90 std::__regex::_StateSet& __e)
92 if (__e.count(__u) == 0)
99 } // anonymous namespace
103 inline _Grep_matcher::
104 _Grep_matcher(_PatternCursor& __p, _Results& __r,
105 const _AutomatonPtr& __nfa,
106 regex_constants::match_flag_type __flags)
107 : _M_nfa(static_pointer_cast<_Nfa>(__nfa)), _M_pattern(__p), _M_results(__r)
109 __regex::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
110 for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
111 __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));
113 _M_results._M_set_matched(0,
114 __includes_some(_M_nfa->_M_final_states(), __t));
117 // Creates the e-closure set for the initial state __i.
118 inline _StateSet _Grep_matcher::
119 _M_e_closure(_StateIdT __i)
125 return this->_M_e_closure(__stack, __s);
128 // Creates the e-closure set for an arbitrary state set __s.
129 inline _StateSet _Grep_matcher::
130 _M_e_closure(const _StateSet& __s)
133 for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i)
135 return this->_M_e_closure(__stack, __s);
138 inline _StateSet _Grep_matcher::
139 _M_e_closure(_StateStack& __stack, const _StateSet& __s)
142 while (!__stack.empty())
144 _StateIdT __t = __stack.top(); __stack.pop();
145 if (__t == _S_invalid_state_id)
147 // for each __u with edge from __t to __u labeled e do ...
148 const _State& __state = _M_nfa->operator[](__t);
149 switch (__state._M_opcode)
151 case _S_opcode_alternative:
152 __add_visited_state(__state._M_next, __stack, __e);
153 __add_visited_state(__state._M_alt, __stack, __e);
155 case _S_opcode_subexpr_begin:
156 __add_visited_state(__state._M_next, __stack, __e);
157 __state._M_tagger(_M_pattern, _M_results);
159 case _S_opcode_subexpr_end:
160 __add_visited_state(__state._M_next, __stack, __e);
161 __state._M_tagger(_M_pattern, _M_results);
162 _M_results._M_set_matched(__state._M_subexpr, true);
164 case _S_opcode_accept:
165 __add_visited_state(__state._M_next, __stack, __e);
174 } // namespace __regex
176 _GLIBCXX_END_NAMESPACE