regex_nfa.tcc

Go to the documentation of this file.
00001 // class template regex -*- C++ -*-
00002 
00003 // Copyright (C) 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /**
00026  * @file bits/regex_nfa.tcc
00027  */
00028 #include <regex>
00029 
00030 namespace std
00031 {
00032 namespace __regex
00033 {
00034 #ifdef _GLIBCXX_DEBUG
00035 inline std::ostream& _State::
00036 _M_print(std::ostream& ostr) const
00037 {
00038   switch (_M_opcode)
00039   {
00040     case _S_opcode_alternative:
00041       ostr << "alt next=" << _M_next << " alt=" << _M_alt;
00042       break;
00043     case _S_opcode_subexpr_begin:
00044       ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
00045       break;
00046     case _S_opcode_subexpr_end:
00047       ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
00048       break;
00049     case _S_opcode_match:
00050       ostr << "match next=" << _M_next;
00051       break;
00052     case _S_opcode_accept:
00053       ostr << "accept next=" << _M_next;
00054       break;
00055     default:
00056       ostr << "unknown next=" << _M_next;
00057       break;
00058   }
00059   return ostr;
00060 }
00061 
00062 // Prints graphviz dot commands for state.
00063 inline std::ostream& _State::
00064 _M_dot(std::ostream& __ostr, _StateIdT __id) const
00065 {
00066   switch (_M_opcode)
00067   {
00068     case _S_opcode_alternative:
00069       __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" 
00070              << __id << " -> " << _M_next
00071              << " [label=\"epsilon\", tailport=\"s\"];\n"
00072              << __id << " -> " << _M_alt 
00073              << " [label=\"epsilon\", tailport=\"n\"];\n";
00074       break;
00075     case _S_opcode_subexpr_begin:
00076       __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
00077              << _M_subexpr << "\"];\n" 
00078              << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
00079       break;
00080     case _S_opcode_subexpr_end:
00081       __ostr << __id << " [label=\"" << __id << "\\nSEND "
00082              << _M_subexpr << "\"];\n" 
00083              << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
00084       break;
00085     case _S_opcode_match:
00086       __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" 
00087              << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
00088       break;
00089     case _S_opcode_accept:
00090       __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
00091       break;
00092     default:
00093       __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" 
00094              << __id << " -> " << _M_next << " [label=\"?\"];\n";
00095       break;
00096   }
00097   return __ostr;
00098 }
00099 
00100 inline std::ostream& _Nfa::
00101 _M_dot(std::ostream& __ostr) const
00102 {
00103   __ostr << "digraph _Nfa {\n"
00104    << "  rankdir=LR;\n";
00105   for (unsigned int __i = 0; __i < this->size(); ++__i)
00106   { this->at(__i)._M_dot(__ostr, __i); }
00107   __ostr << "}\n";
00108   return __ostr;
00109 }
00110 #endif
00111 
00112 inline _StateSeq& _StateSeq::
00113 operator=(const _StateSeq& __rhs)
00114 {
00115   _M_start = __rhs._M_start;
00116   _M_end1  = __rhs._M_end1;
00117   _M_end2  = __rhs._M_end2;
00118   return *this;
00119 }
00120 
00121 inline void _StateSeq::
00122 _M_push_back(_StateIdT __id)
00123 {
00124   if (_M_end1 != _S_invalid_state_id)
00125     _M_nfa[_M_end1]._M_next = __id;
00126   _M_end1 = __id;
00127 }
00128 
00129 inline void _StateSeq::
00130 _M_append(_StateIdT __id)
00131 {
00132   if (_M_end2 != _S_invalid_state_id)
00133   {
00134     if (_M_end2 == _M_end1)
00135       _M_nfa[_M_end2]._M_alt = __id;
00136     else
00137       _M_nfa[_M_end2]._M_next = __id;
00138     _M_end2 = _S_invalid_state_id;
00139   }
00140   if (_M_end1 != _S_invalid_state_id)
00141     _M_nfa[_M_end1]._M_next = __id;
00142   _M_end1 = __id;
00143 }
00144 
00145 inline void _StateSeq::
00146 _M_append(_StateSeq& __rhs)
00147 {
00148   if (_M_end2 != _S_invalid_state_id)
00149   {
00150     if (_M_end2 == _M_end1)
00151       _M_nfa[_M_end2]._M_alt = __rhs._M_start;
00152     else
00153       _M_nfa[_M_end2]._M_next = __rhs._M_start;
00154     _M_end2 = _S_invalid_state_id;
00155   }
00156   if (__rhs._M_end2 != _S_invalid_state_id)
00157     _M_end2 = __rhs._M_end2;
00158   if (_M_end1 != _S_invalid_state_id)
00159     _M_nfa[_M_end1]._M_next = __rhs._M_start;
00160   _M_end1 = __rhs._M_end1;
00161 }
00162 
00163 // @todo implement this function.
00164 inline _StateIdT _StateSeq::
00165 _M_clone()
00166 { return 0; }
00167 
00168 } // namespace __regex
00169 } // namespace std
00170