1// class template regex -*- C++ -*- 2 3// Copyright (C) 2010, 2011 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_nfa.tcc 27 * This is an internal header file, included by other library headers. 28 * Do not attempt to use it directly. @headername{regex} 29 */ 30#include <regex> 31 32namespace std _GLIBCXX_VISIBILITY(default) 33{ 34namespace __regex 35{ 36_GLIBCXX_BEGIN_NAMESPACE_VERSION 37 38#ifdef _GLIBCXX_DEBUG 39inline std::ostream& _State:: 40_M_print(std::ostream& ostr) const 41{ 42 switch (_M_opcode) 43 { 44 case _S_opcode_alternative: 45 ostr << "alt next=" << _M_next << " alt=" << _M_alt; 46 break; 47 case _S_opcode_subexpr_begin: 48 ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr; 49 break; 50 case _S_opcode_subexpr_end: 51 ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr; 52 break; 53 case _S_opcode_match: 54 ostr << "match next=" << _M_next; 55 break; 56 case _S_opcode_accept: 57 ostr << "accept next=" << _M_next; 58 break; 59 default: 60 ostr << "unknown next=" << _M_next; 61 break; 62 } 63 return ostr; 64} 65 66// Prints graphviz dot commands for state. 67inline std::ostream& _State:: 68_M_dot(std::ostream& __ostr, _StateIdT __id) const 69{ 70 switch (_M_opcode) 71 { 72 case _S_opcode_alternative: 73 __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" 74 << __id << " -> " << _M_next 75 << " [label=\"epsilon\", tailport=\"s\"];\n" 76 << __id << " -> " << _M_alt 77 << " [label=\"epsilon\", tailport=\"n\"];\n"; 78 break; 79 case _S_opcode_subexpr_begin: 80 __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " 81 << _M_subexpr << "\"];\n" 82 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; 83 break; 84 case _S_opcode_subexpr_end: 85 __ostr << __id << " [label=\"" << __id << "\\nSEND " 86 << _M_subexpr << "\"];\n" 87 << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; 88 break; 89 case _S_opcode_match: 90 __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" 91 << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; 92 break; 93 case _S_opcode_accept: 94 __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; 95 break; 96 default: 97 __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" 98 << __id << " -> " << _M_next << " [label=\"?\"];\n"; 99 break; 100 } 101 return __ostr; 102} 103 104inline std::ostream& _Nfa:: 105_M_dot(std::ostream& __ostr) const 106{ 107 __ostr << "digraph _Nfa {\n" 108 << " rankdir=LR;\n"; 109 for (unsigned int __i = 0; __i < this->size(); ++__i) 110 { this->at(__i)._M_dot(__ostr, __i); } 111 __ostr << "}\n"; 112 return __ostr; 113} 114#endif 115 116inline _StateSeq& _StateSeq:: 117operator=(const _StateSeq& __rhs) 118{ 119 _M_start = __rhs._M_start; 120 _M_end1 = __rhs._M_end1; 121 _M_end2 = __rhs._M_end2; 122 return *this; 123} 124 125inline void _StateSeq:: 126_M_push_back(_StateIdT __id) 127{ 128 if (_M_end1 != _S_invalid_state_id) 129 _M_nfa[_M_end1]._M_next = __id; 130 _M_end1 = __id; 131} 132 133inline void _StateSeq:: 134_M_append(_StateIdT __id) 135{ 136 if (_M_end2 != _S_invalid_state_id) 137 { 138 if (_M_end2 == _M_end1) 139 _M_nfa[_M_end2]._M_alt = __id; 140 else 141 _M_nfa[_M_end2]._M_next = __id; 142 _M_end2 = _S_invalid_state_id; 143 } 144 if (_M_end1 != _S_invalid_state_id) 145 _M_nfa[_M_end1]._M_next = __id; 146 _M_end1 = __id; 147} 148 149inline void _StateSeq:: 150_M_append(_StateSeq& __rhs) 151{ 152 if (_M_end2 != _S_invalid_state_id) 153 { 154 if (_M_end2 == _M_end1) 155 _M_nfa[_M_end2]._M_alt = __rhs._M_start; 156 else 157 _M_nfa[_M_end2]._M_next = __rhs._M_start; 158 _M_end2 = _S_invalid_state_id; 159 } 160 if (__rhs._M_end2 != _S_invalid_state_id) 161 _M_end2 = __rhs._M_end2; 162 if (_M_end1 != _S_invalid_state_id) 163 _M_nfa[_M_end1]._M_next = __rhs._M_start; 164 _M_end1 = __rhs._M_end1; 165} 166 167// @todo implement this function. 168inline _StateIdT _StateSeq:: 169_M_clone() 170{ return 0; } 171 172_GLIBCXX_END_NAMESPACE_VERSION 173} // namespace __regex 174} // namespace 175