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

choice.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_PARSERCHOICE_H
00021 #define GRAMMAR_TO_PARSERCHOICE_H
00022 
00023 #include "non_terminal.h"
00024 
00025 namespace grammar_to_parser {
00026 
00027 const char* CHOICE = "Choice";
00028 
00036 template <typename E, typename A>
00037 class basic_choice : 
00038         public basic_non_terminal<E,A>
00039 {
00040 public:
00041 typedef typename basic_parser<E>::parser_list parser_list;
00042 typedef typename basic_parser<E>::parser_list_iterator parser_list_iterator;
00043 
00045     basic_choice();
00046         
00048         basic_choice( const basic_choice& rhs );
00049         
00051         basic_choice( const A& obj );
00052         
00053         
00055     virtual ~basic_choice();
00056 
00064     virtual unsigned long parse( const E *buf, const unsigned long buf_length );
00065 
00069     virtual unsigned long parse( const E *buf, 
00070                                                                 const unsigned long buf_length,
00071                                                                 basic_parser_strategy<E>& strategy);
00072 
00077         virtual std::basic_istream<E>& parse( std::basic_istream<E>& is );      
00078 };
00079 
00083 template <typename A>
00084 class choice : public basic_choice<char,A>
00085 {
00086 public:
00087     
00088         choice() : basic_choice<char,A>() {};
00089         choice(const choice& rhs) : 
00090                 basic_choice<char,A>( rhs ) {};
00091         choice(const A& obj) : 
00092                 basic_choice<char,A>(obj) {};
00093     virtual ~choice() {};
00094 };
00095 
00099 template <typename A>
00100 class wchoice : public basic_choice<wchar_t,A>
00101 {       
00102 public: 
00103         
00104     wchoice() : basic_choice<wchar_t,A>() {};
00105         wchoice(const wchoice& rhs) : 
00106                 basic_choice<wchar_t,A>( rhs ) {};
00107         wchoice(const A& obj) : 
00108                 basic_choice<wchar_t,A>(obj) {};
00109         virtual ~wchoice() {};
00110 };
00111 
00112 // IMPLEMENTATION
00113 template< typename E, typename A >
00114 basic_choice<E,A>::basic_choice()
00115  : basic_non_terminal<E,A>()
00116 {
00117         set_name( CHOICE );
00118 }
00119 
00120 template< typename E, typename A >
00121 basic_choice<E,A>::basic_choice( const basic_choice& rhs )
00122  : basic_non_terminal<E,A>(rhs)
00123 {
00124         set_name( CHOICE );
00125 };
00126 
00127 template< typename E, typename A >
00128 basic_choice<E,A>::basic_choice( const A& obj )
00129  : basic_non_terminal<E,A>(obj)
00130 {
00131         set_name( CHOICE );
00132 };
00133 
00134 template< typename E, typename A >
00135 basic_choice<E,A>::~basic_choice()
00136 {
00137         set_name( CHOICE );
00138 }
00139 
00140 template< typename E, typename A >
00141 unsigned long basic_choice<E,A>::parse( const E *buf, 
00142                                                                                 const unsigned long buf_length )
00143 {
00144         prepare_for_parsing();
00145         
00146         parser_list_iterator parse_iterator = m_symbols.begin();
00147         while( parse_iterator != m_symbols.end() && !m_is_parsed )
00148         {
00149                 // try to parse any of the symbols, stop when
00150                 // found the first successive parser
00151                 m_parsed_size = (*parse_iterator)->parse(buf, buf_length);
00152                 m_is_parsed = (*parse_iterator)->is_parsed();
00153                 if( !m_is_parsed )  
00154                 {
00155                         (*parse_iterator)->invalidate();
00156                 }
00157                 parse_iterator++;
00158         }
00159         // unset 'parsed' flag for rest (for parser reuse)
00160         while( parse_iterator != m_symbols.end() )
00161         {
00162                 (*parse_iterator++)->invalidate();
00163         }
00164         return m_parsed_size;
00165 }
00166 
00167 template< typename E, typename A >
00168 std::basic_istream<E>& basic_choice<E,A>::parse( std::basic_istream<E>& is )
00169 {
00170         prepare_for_parsing();
00171         parser_list_iterator parse_iterator = m_symbols.begin();
00172         
00173         std::streampos stream_pos = is.tellg();
00174         if( (std::streamoff)stream_pos < 0 ) stream_pos = 0;
00175 
00176         while(  parse_iterator != m_symbols.end() &&
00177                         !is.bad() && 
00178                         !m_is_parsed )
00179         {
00180                 (*parse_iterator)->parse( is );
00181                 m_parsed_size = (*parse_iterator)->parsed_size();
00182                 m_is_parsed = (*parse_iterator)->is_parsed();
00183                 if( !m_is_parsed )  
00184                 {
00185                         (*parse_iterator)->invalidate();
00186                 }
00187                 parse_iterator++;
00188         }
00189 
00190 
00191         // unset 'parsed' flag for rest (for parser reuse)
00192         while( parse_iterator != m_symbols.end() )
00193         {
00194                 (*parse_iterator++)->invalidate();
00195         }
00196 
00197         // reset the starting os buf possition in case of error
00198         if( parse_iterator != m_symbols.end() )
00199         {
00200                 is.clear();
00201                 is.seekg( stream_pos );
00202                 m_parsed_size = 0;
00203         }
00204         return is;
00205 }
00206 
00207 template< typename E, typename A >
00208 unsigned long basic_choice<E,A>::parse( const E *buf, 
00209                                                                                 const unsigned long buf_length,
00210                                                                                 basic_parser_strategy<E>& strategy )
00211 {
00212         prepare_for_parsing();
00213         m_is_parsed = strategy.parse_choice( m_symbols.begin(),
00214                                                                         m_symbols.end(), 
00215                                                                         buf, 
00216                                                                         buf_length, 
00217                                                                         m_parsed_size );
00218         return m_parsed_size;
00219 }
00220 
00221 };
00222 
00223 #endif

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