1 // class template regex -*- C++ -*- 2 3 // Copyright (C) 2010-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_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 32 namespace std _GLIBCXX_VISIBILITY(default) 33 { 34 namespace __detail 35 { 36 _GLIBCXX_BEGIN_NAMESPACE_VERSION 37 38 #ifdef _GLIBCXX_DEBUG 39 inline 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. 67 inline 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 104 inline 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 116 inline _StateSeq& _StateSeq:: 117 operator=(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 125 inline 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 133 inline 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 149 inline 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. 168 inline _StateIdT _StateSeq:: 169 _M_clone() 170 { return 0; } 171 172 _GLIBCXX_END_NAMESPACE_VERSION 173 } // namespace __detail 174 } // namespace 175