xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/regex_grep_matcher.tcc (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // class template regex -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2010 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino // any later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*e4b17023SJohn Marino // GNU General Public License for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /**
26*e4b17023SJohn Marino  *  @file bits/regex_grep_matcher.tcc
27*e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
28*e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{regex}
29*e4b17023SJohn Marino  */
30*e4b17023SJohn Marino 
31*e4b17023SJohn Marino #include <regex>
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
34*e4b17023SJohn Marino {
35*e4b17023SJohn Marino namespace
36*e4b17023SJohn Marino {
37*e4b17023SJohn Marino   // A stack of states used in evaluating the NFA.
38*e4b17023SJohn Marino   typedef std::stack<std::__regex::_StateIdT,
39*e4b17023SJohn Marino                      std::vector<std::__regex::_StateIdT>
40*e4b17023SJohn Marino 		     > _StateStack;
41*e4b17023SJohn Marino 
42*e4b17023SJohn Marino   // Obtains the next state set given the current state set __s and the current
43*e4b17023SJohn Marino   // input character.
44*e4b17023SJohn Marino   inline std::__regex::_StateSet
__move(const std::__regex::_PatternCursor & __p,const std::__regex::_Nfa & __nfa,const std::__regex::_StateSet & __s)45*e4b17023SJohn Marino   __move(const std::__regex::_PatternCursor& __p,
46*e4b17023SJohn Marino          const std::__regex::_Nfa& __nfa,
47*e4b17023SJohn Marino          const std::__regex::_StateSet& __s)
48*e4b17023SJohn Marino   {
49*e4b17023SJohn Marino     std::__regex::_StateSet __m;
50*e4b17023SJohn Marino     for (std::__regex::_StateSet::const_iterator __i = __s.begin();
51*e4b17023SJohn Marino 	 __i != __s.end(); ++__i)
52*e4b17023SJohn Marino       {
53*e4b17023SJohn Marino 	if (*__i == std::__regex::_S_invalid_state_id)
54*e4b17023SJohn Marino 	  continue;
55*e4b17023SJohn Marino 
56*e4b17023SJohn Marino 	const std::__regex::_State& __state = __nfa[*__i];
57*e4b17023SJohn Marino 	if (__state._M_opcode == std::__regex::_S_opcode_match
58*e4b17023SJohn Marino 	    && __state._M_matches(__p))
59*e4b17023SJohn Marino 	  __m.insert(__state._M_next);
60*e4b17023SJohn Marino       }
61*e4b17023SJohn Marino     return __m;
62*e4b17023SJohn Marino   }
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   // returns true if (__s intersect __t) is not empty
65*e4b17023SJohn Marino   inline bool
__includes_some(const std::__regex::_StateSet & __s,const std::__regex::_StateSet & __t)66*e4b17023SJohn Marino   __includes_some(const std::__regex::_StateSet& __s,
67*e4b17023SJohn Marino                   const std::__regex::_StateSet& __t)
68*e4b17023SJohn Marino   {
69*e4b17023SJohn Marino     if (__s.size() > 0 && __t.size() > 0)
70*e4b17023SJohn Marino       {
71*e4b17023SJohn Marino 	std::__regex::_StateSet::const_iterator __first = __s.begin();
72*e4b17023SJohn Marino 	std::__regex::_StateSet::const_iterator __second = __t.begin();
73*e4b17023SJohn Marino 	while (__first != __s.end() && __second != __t.end())
74*e4b17023SJohn Marino 	  {
75*e4b17023SJohn Marino 	    if (*__first < *__second)
76*e4b17023SJohn Marino 	      ++__first;
77*e4b17023SJohn Marino 	    else if (*__second < *__first)
78*e4b17023SJohn Marino 	      ++__second;
79*e4b17023SJohn Marino 	    else
80*e4b17023SJohn Marino 	      return true;
81*e4b17023SJohn Marino 	  }
82*e4b17023SJohn Marino       }
83*e4b17023SJohn Marino     return false;
84*e4b17023SJohn Marino   }
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino   // If an identified state __u is not already in the current state set __e,
87*e4b17023SJohn Marino   // insert it and push it on the current state stack __s.
88*e4b17023SJohn Marino   inline void
__add_visited_state(const std::__regex::_StateIdT __u,_StateStack & __s,std::__regex::_StateSet & __e)89*e4b17023SJohn Marino   __add_visited_state(const std::__regex::_StateIdT __u,
90*e4b17023SJohn Marino                       _StateStack&                  __s,
91*e4b17023SJohn Marino                       std::__regex::_StateSet&      __e)
92*e4b17023SJohn Marino   {
93*e4b17023SJohn Marino     if (__e.count(__u) == 0)
94*e4b17023SJohn Marino       {
95*e4b17023SJohn Marino 	__e.insert(__u);
96*e4b17023SJohn Marino 	__s.push(__u);
97*e4b17023SJohn Marino       }
98*e4b17023SJohn Marino   }
99*e4b17023SJohn Marino 
100*e4b17023SJohn Marino } // anonymous namespace
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino namespace __regex
103*e4b17023SJohn Marino {
104*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino   inline _Grep_matcher::
_Grep_matcher(_PatternCursor & __p,_Results & __r,const _AutomatonPtr & __nfa,regex_constants::match_flag_type __flags)107*e4b17023SJohn Marino   _Grep_matcher(_PatternCursor& __p, _Results& __r,
108*e4b17023SJohn Marino 		const _AutomatonPtr& __nfa,
109*e4b17023SJohn Marino 		regex_constants::match_flag_type __flags)
110*e4b17023SJohn Marino   : _M_nfa(static_pointer_cast<_Nfa>(__nfa)), _M_pattern(__p), _M_results(__r)
111*e4b17023SJohn Marino   {
112*e4b17023SJohn Marino     __regex::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
113*e4b17023SJohn Marino     for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
114*e4b17023SJohn Marino       __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino     _M_results._M_set_matched(0,
117*e4b17023SJohn Marino                               __includes_some(_M_nfa->_M_final_states(), __t));
118*e4b17023SJohn Marino   }
119*e4b17023SJohn Marino 
120*e4b17023SJohn Marino   // Creates the e-closure set for the initial state __i.
121*e4b17023SJohn Marino   inline _StateSet _Grep_matcher::
_M_e_closure(_StateIdT __i)122*e4b17023SJohn Marino   _M_e_closure(_StateIdT __i)
123*e4b17023SJohn Marino   {
124*e4b17023SJohn Marino     _StateSet __s;
125*e4b17023SJohn Marino     __s.insert(__i);
126*e4b17023SJohn Marino     _StateStack __stack;
127*e4b17023SJohn Marino     __stack.push(__i);
128*e4b17023SJohn Marino     return this->_M_e_closure(__stack, __s);
129*e4b17023SJohn Marino   }
130*e4b17023SJohn Marino 
131*e4b17023SJohn Marino   // Creates the e-closure set for an arbitrary state set __s.
132*e4b17023SJohn Marino   inline _StateSet _Grep_matcher::
_M_e_closure(const _StateSet & __s)133*e4b17023SJohn Marino   _M_e_closure(const _StateSet& __s)
134*e4b17023SJohn Marino   {
135*e4b17023SJohn Marino     _StateStack __stack;
136*e4b17023SJohn Marino     for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i)
137*e4b17023SJohn Marino       __stack.push(*__i);
138*e4b17023SJohn Marino     return this->_M_e_closure(__stack, __s);
139*e4b17023SJohn Marino   }
140*e4b17023SJohn Marino 
141*e4b17023SJohn Marino   inline _StateSet _Grep_matcher::
_M_e_closure(_StateStack & __stack,const _StateSet & __s)142*e4b17023SJohn Marino   _M_e_closure(_StateStack& __stack, const _StateSet& __s)
143*e4b17023SJohn Marino   {
144*e4b17023SJohn Marino     _StateSet __e = __s;
145*e4b17023SJohn Marino     while (!__stack.empty())
146*e4b17023SJohn Marino       {
147*e4b17023SJohn Marino 	_StateIdT __t = __stack.top(); __stack.pop();
148*e4b17023SJohn Marino 	if (__t == _S_invalid_state_id)
149*e4b17023SJohn Marino 	  continue;
150*e4b17023SJohn Marino 	// for each __u with edge from __t to __u labeled e do ...
151*e4b17023SJohn Marino 	const _State& __state = _M_nfa->operator[](__t);
152*e4b17023SJohn Marino 	switch (__state._M_opcode)
153*e4b17023SJohn Marino 	  {
154*e4b17023SJohn Marino 	  case _S_opcode_alternative:
155*e4b17023SJohn Marino 	    __add_visited_state(__state._M_next, __stack, __e);
156*e4b17023SJohn Marino 	    __add_visited_state(__state._M_alt, __stack, __e);
157*e4b17023SJohn Marino 	    break;
158*e4b17023SJohn Marino 	  case _S_opcode_subexpr_begin:
159*e4b17023SJohn Marino 	    __add_visited_state(__state._M_next, __stack, __e);
160*e4b17023SJohn Marino 	    __state._M_tagger(_M_pattern, _M_results);
161*e4b17023SJohn Marino 	    break;
162*e4b17023SJohn Marino 	  case _S_opcode_subexpr_end:
163*e4b17023SJohn Marino 	    __add_visited_state(__state._M_next, __stack, __e);
164*e4b17023SJohn Marino 	    __state._M_tagger(_M_pattern, _M_results);
165*e4b17023SJohn Marino 	    _M_results._M_set_matched(__state._M_subexpr, true);
166*e4b17023SJohn Marino 	    break;
167*e4b17023SJohn Marino 	  case _S_opcode_accept:
168*e4b17023SJohn Marino 	    __add_visited_state(__state._M_next, __stack, __e);
169*e4b17023SJohn Marino 	    break;
170*e4b17023SJohn Marino 	  default:
171*e4b17023SJohn Marino 	    break;
172*e4b17023SJohn Marino 	  }
173*e4b17023SJohn Marino       }
174*e4b17023SJohn Marino     return __e;
175*e4b17023SJohn Marino   }
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
178*e4b17023SJohn Marino } // namespace __regex
179*e4b17023SJohn Marino } // namespace
180