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

non_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_PARSERNON_TERMINAL_H
00021 #define GRAMMAR_TO_PARSERNON_TERMINAL_H
00022 
00023 
00024 namespace grammar_to_parser {
00025 
00026 const char* NONTERMINAL = "non-terminal";
00036 template<typename E, typename A >
00037 class basic_non_terminal : public basic_object_parser<E,A>
00038 {
00039 public: 
00040 typedef typename basic_parser<E>::parser_list parser_list;
00041 typedef typename basic_parser<E>::parser_list_iterator parser_list_iterator;
00042 
00044     basic_non_terminal();
00046         basic_non_terminal( const A& obj );
00048         basic_non_terminal( const basic_non_terminal& rhs );
00050     ~basic_non_terminal();
00051         
00058     virtual unsigned long parse( const E *buf, 
00059                                                                 const unsigned long buf_length );
00060 
00064     virtual unsigned long parse( const E *buf, 
00065                                                                 const unsigned long buf_length,
00066                                                                 basic_parser_strategy<E>& strategy );
00067         
00074         virtual std::basic_istream<E>& parse( std::basic_istream<E>& is );
00075 
00082     virtual std::basic_ostream<E>& format( std::basic_ostream<E>& os );
00083 
00088         void invalidate() 
00089         { 
00090                 m_symbols.clear();
00091                 m_symbols_valid = false;
00092                 basic_object_parser<E,A>::invalidate();
00093         }
00094 
00095 
00096 protected:
00101         parser_list                     m_symbols;
00105         bool                            m_symbols_valid;
00106 
00108         virtual void prepare_symbols() 
00109         { 
00110                 if( !m_symbols_valid ) 
00111                 {
00112                         get_valid().push_parsers( m_symbols );
00113                         m_symbols_valid = true;
00114                 }
00115         }
00116         
00118         void prepare_for_parsing()
00119         {
00120                 basic_object_parser<E,A>::prepare_for_parsing();
00121                 prepare_symbols();
00122                 parser_list_iterator it = m_symbols.begin();
00123 
00124         }
00125         
00127         void prepare_for_formatting()
00128         {
00129                 basic_object_parser<E,A>::prepare_for_formatting();
00130                 prepare_symbols();
00131         }
00132 };
00133 
00137 template<typename A>
00138 class non_terminal : public basic_non_terminal<char,A>
00139 {
00140 public:
00141     non_terminal() : basic_non_terminal<char,A>() {};
00142         non_terminal( const A& obj ) :
00143                         basic_non_terminal<char,A>(obj) {};
00144         non_terminal( const non_terminal& rhs ) : 
00145                         basic_non_terminal<char,A>(rhs) {};
00146     ~non_terminal() {};
00147 };
00148 
00152 template<typename A>
00153 class wnon_terminal : public basic_non_terminal<wchar_t,A>
00154 {
00155 public:
00156     wnon_terminal() : basic_non_terminal<wchar_t,A>() {};
00157         wnon_terminal( const A& obj ) :
00158                         basic_non_terminal<wchar_t,A>(obj) {};
00159         wnon_terminal( const wnon_terminal& rhs ) : 
00160                         basic_non_terminal<wchar_t,A>(rhs) {};
00161     ~wnon_terminal() {};
00162 };
00163 
00164 
00165 template< typename E, typename A >
00166 basic_non_terminal<E,A>::basic_non_terminal()
00167  : basic_object_parser<E,A>(NONTERMINAL,basic_parser<E>::non_terminal_type),
00168   m_symbols_valid(false)
00169 {
00170 }
00171 
00172 template< typename E, typename A >
00173 basic_non_terminal<E,A>::basic_non_terminal( const A& obj  )
00174  :      basic_object_parser<E,A>(NONTERMINAL,obj, basic_parser<E>::non_terminal_type ), 
00175         m_symbols_valid(false)
00176 {
00177 };
00178 
00179 template< typename E, typename A >
00180 basic_non_terminal<E,A>::basic_non_terminal(
00181                                                                          const basic_non_terminal& rhs )
00182  :      basic_object_parser<E,A>(rhs),
00183         m_symbols_valid(false)
00184 {
00185 };
00186         
00187 template< typename E, typename A>
00188 basic_non_terminal<E,A>::~basic_non_terminal()
00189 {
00190 }
00191 
00192 template< typename E, typename A>
00193 std::basic_istream<E>& basic_non_terminal<E,A>
00194  ::parse( std::basic_istream<E>& is )
00195 {
00196         prepare_for_parsing();
00197         parser_list_iterator parse_iterator = m_symbols.begin();
00198         
00199         bool is_parsed = true;
00200         std::streampos stream_pos = is.tellg();
00201         if( (std::streamoff)stream_pos < 0 ) stream_pos = 0;
00202 
00203         while(  parse_iterator != m_symbols.end() &&
00204                         !is.bad() && 
00205                         is_parsed )
00206         {
00207                 (*parse_iterator)->parse( is );
00208                 m_parsed_size += (*parse_iterator)->parsed_size();
00209                 is_parsed = (*parse_iterator)->is_parsed();
00210                 parse_iterator++;
00211         }
00212         // reset the starting os buf possition in case of error
00213         if( parse_iterator != m_symbols.end() || !is_parsed)
00214         {
00215                 is.clear();
00216                 is.seekg( stream_pos );
00217                 m_parsed_size = 0;
00218         }
00219         else m_is_parsed = true;
00220         return is;
00221 }
00222 
00223 template< typename E, typename A >
00224 std::basic_ostream<E>& basic_non_terminal<E,A>
00225  ::format( std::basic_ostream<E>& os )
00226 {
00227         prepare_for_formatting();
00228         parser_list_iterator format_iterator = m_symbols.begin();
00229         
00230         bool is_formatted = true;
00231         std::streampos streamPos = os.tellp();
00232         if( (std::streamoff)streamPos < 0 ) streamPos = 0;
00233 
00234         while(  format_iterator != m_symbols.end() &&
00235                         !os.bad() && 
00236                         is_formatted )
00237         {
00238                 if( (*format_iterator)->is_valid() )
00239                 {
00240                         (*format_iterator)->format( os );
00241                         m_formatted_size += (*format_iterator)->formatted_size();
00242                         is_formatted = (*format_iterator)->is_formatted();
00243                 }
00244                 format_iterator++;
00245         }
00246         // reset the starting os buf possition in case of error
00247         if( format_iterator != m_symbols.end() || !is_formatted)
00248         {
00249                 os.clear();
00250                 os.seekp( streamPos );
00251                 m_formatted_size = 0;
00252         }
00253         else m_is_formatted = true;
00254         return os;
00255 }
00256 
00257 template< typename E, typename A >
00258 unsigned long basic_non_terminal<E,A>
00259  ::parse( const E *buf, const unsigned long buf_length )
00260 {
00261         prepare_for_parsing();
00262         parser_list_iterator parse_iterator = m_symbols.begin();
00263         
00264         bool is_parsed = true;
00265 
00266         while(  parse_iterator != m_symbols.end() && is_parsed )
00267         {
00268                 (*parse_iterator)->parse( buf+m_parsed_size, buf_length-m_parsed_size );
00269                 m_parsed_size += (*parse_iterator)->parsed_size();
00270                 is_parsed = (*parse_iterator)->is_parsed();
00271                 parse_iterator++;
00272         }
00273         // reset the starting os buf possition in case of error
00274         if( !is_parsed )
00275         {
00276                 m_parsed_size = 0;
00277         }
00278         else
00279         {
00280                 m_is_parsed = true;
00281         }
00282         return m_parsed_size;
00283 }
00284 
00285 template< typename E, typename A >
00286 unsigned long basic_non_terminal<E,A>::parse( 
00287                                                                                 const E *buf, 
00288                                                                                 const unsigned long buf_length,
00289                                                                                 basic_parser_strategy<E>& strategy )
00290 {
00291         prepare_for_parsing();
00292         m_is_parsed = strategy.parse_all( m_symbols.begin(),
00293                                                                         m_symbols.end(), 
00294                                                                         buf, 
00295                                                                         buf_length, 
00296                                                                         m_parsed_size );
00297         return m_parsed_size;
00298         
00299 }
00300 
00301 };
00302 
00303 #endif

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