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