00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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