Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

terminal.h

00001 /***************************************************************************
00002  *   Copyright (C) 2004-2006 by Radko Mihal                                *
00003  *   rmihal@pobox.sk                                                       *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
00019  ***************************************************************************/
00020 #ifndef GRAMMAR_TO_PARSERTERMINAL_H
00021 #define GRAMMAR_TO_PARSERTERMINAL_H
00022 
00023 namespace grammar_to_parser {
00024 
00025 const char* TERMINAL = "terminal";
00037 template< typename E, E value >
00038 class basic_terminal : public basic_object_parser< E, E >
00039 {
00040 typedef std::auto_ptr<E> std_auto_ptr;
00041 public:
00042     basic_terminal();
00043     virtual ~basic_terminal();
00044         
00045         virtual unsigned long parse( const E *buf, 
00046                                                         const unsigned long buf_length )
00047         {
00048                 prepare_for_parsing();
00049                 
00050 #ifdef TRACE 
00051                 if( buf_length > 0 )
00052                 {
00053                         cout << "terminal " << std::string(1,value).c_str();
00054                         cout << ", input=" << std::string(1,buf[0]).c_str() << endl;
00055                 }
00056 #endif
00057 
00058                 if( buf_length > 0 && 
00059                         (E)buf[0] == get_valid() )
00060                 {
00061                         m_is_parsed = true;
00062                         m_parsed_size = 1;//sizeof(value);
00063                 }
00064                 return m_parsed_size;
00065         }    
00066         virtual std::basic_istream<E>& parse( std::basic_istream<E>& is );
00067                         
00068         virtual std::basic_ostream<E>& format( std::basic_ostream<E>& os );    
00069 
00070         // during allocation the value is assigned to unsigned char - for 
00071         // comparison during parsing
00072         E& get_valid()
00073         {
00074                 if( !is_valid() ) 
00075                 {
00076                         std_auto_ptr::operator=( std_auto_ptr(new E(value)) );
00077                 }
00078                 return std_auto_ptr::operator *();
00079 
00080         }
00081 };
00082 
00086 template< char value >
00087 class terminal : public basic_terminal<char,value>
00088 {
00089 public:
00090         terminal() : basic_terminal<char,value>() {};
00091         ~terminal() {};
00092 };
00093 
00097 template< wchar_t value >
00098 class wterminal : public basic_terminal<wchar_t,value>
00099 {
00100 public:
00101         wterminal() : basic_terminal<wchar_t,value> () {};
00102         ~wterminal() {};
00103 };
00104 
00105 
00106 template< class E, E value >
00107 basic_terminal<E,value>::basic_terminal() : basic_object_parser<E,E>(TERMINAL) 
00108 {
00109 }
00110 
00111 template< typename E, E value >
00112 basic_terminal<E,value>::~basic_terminal()
00113 {
00114 }
00115 
00119 template< typename E, E value >
00120 std::basic_ostream<E>& basic_terminal<E,value>::format( std::basic_ostream<E>& os )
00121 {
00122         prepare_for_formatting();
00123 
00124         std::streampos strPos = os.tellp();
00125         if( (std::streamoff)strPos < 0 ) strPos = 0;
00126 
00127         E out = get_valid();
00128         if( os.good() ) 
00129         {
00130                 os.write( (E*)&out,sizeof(E) );
00131                 m_formatted_size = sizeof(E);
00132                 m_is_formatted = true;
00133         }
00134         else 
00135         {
00136                 os.clear();
00137                 os.seekp( strPos );
00138         }
00139         return os;
00140 }
00141 
00142 template< typename E, E value >
00143 std::basic_istream<E>& basic_terminal<E,value>::parse( std::basic_istream<E>& is )
00144 {
00145 typedef std::basic_istream<E> std_is;
00146         
00147         prepare_for_parsing();
00148         if( !is.good() )
00149         {
00150                 return is;
00151         }
00152         E input = get_valid();
00153         std::streampos str_pos = is.tellg();
00154 
00155         is.read( &input, 1 );
00156         
00157 #ifdef TRACE 
00158         cout << "terminal " << std::string(1,value).c_str();
00159         cout << ", input=" << std::string(1,input).c_str() << endl;
00160 #endif
00161 
00162         if( is.good() && get_valid() == input )
00163         {
00164                 m_parsed_size = 1;
00165                 m_is_parsed = true;
00166         }
00167         else 
00168         {
00169                 is.clear();
00170                 is.seekg( str_pos );
00171         }
00172         return is;
00173 }
00174 
00175 };
00176 
00177 #endif

Generated on Sun Jul 2 18:39:43 2006 for grammar2parser.kdevelop by  doxygen 1.4.1