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

pattern_parser.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_PARSERPATTERN_PARSER_H
00021 #define GRAMMAR_TO_PARSERPATTERN_PARSER_H
00022 
00023 #include "default_type_parser.h"
00024 #include "ctype.h"
00025 
00026 namespace grammar_to_parser {
00027 
00028 const char* PATTERN_PARSER = "PatternParser";
00032 template< typename E >
00033 class basic_pattern_parser : 
00034         public basic_default_type_parser< E, std::basic_string<E> >
00035 {
00036 public:
00037 typedef std::basic_string<E>    string_type;
00039     basic_pattern_parser() : 
00040                         basic_default_type_parser< E, string_type >(PATTERN_PARSER) {};
00046         basic_pattern_parser( const std::basic_string<E>& pattern, 
00047                                         int comparison_type = IGNORE_CASE | IGNORE_SPACE ) :
00048                 basic_default_type_parser< E, string_type >(pattern,PATTERN_PARSER),
00049                 comparison_type_(comparison_type) {};
00050                                 
00051         basic_pattern_parser( const char *pattern, 
00052                                         int comparison_type = IGNORE_CASE | IGNORE_SPACE ) :
00053                 basic_default_type_parser< E, string_type >(widen(pattern),PATTERN_PARSER),
00054                 comparison_type_(comparison_type) {};
00055         
00057     ~basic_pattern_parser() {};
00065         virtual unsigned long parse( const E *buf, const unsigned long buf_length );
00066 
00070         std::basic_istream<E>& parse( std::basic_istream<E>& is );
00071 
00072         std::basic_string<E> widen( const char* pattern )
00073         {
00074                 // TODO - use constructor with input of pattern, as it must be stored 
00075                 // the while pattern including spaces
00076                 std::basic_stringstream<E> ss;
00077                 ss << pattern;
00078                 return ss.str();
00079                 /*std::string str_pattern = pattern;
00080                 E* dest = new E[str_pattern.length()];
00081                 // std::use_facet< std::ctype<E> >().widen( pattern, pattern+str_pattern.length(), dest );
00082                 std::basic_string<E> ret = dest;
00083                 delete[] dest;
00084                 return ret;*/
00085         }
00086 protected:
00090         enum comparison_type
00091         {
00092                 IGNORE_SPACE = 1, 
00093                 IGNORE_CASE = 2 
00094         };
00096         int comparison_type_;
00097 
00098 private:
00099         // TODO  - use ctype<E> locale to compare national specific letters
00100         bool is_capital( const char cr ) {return cr >= 'A' && cr <= 'Z';}
00101         bool is_space( const char cr ) {return cr == ' ' || cr == '\t' || cr == '\n';}
00102         bool compare( typename string_type::iterator& it, const E cr )
00103         {
00104                 if( (*it) == cr || 
00105                         ( (comparison_type_ & IGNORE_CASE ) &&
00106                         ( is_capital(cr) && (cr-'A') == ((*it)-'a') ||
00107                                 is_capital(*it) && ((*it)-'A') == (cr-'a') ) ) )
00108                 {
00109                         it++;
00110                         return true;
00111                 }
00112                 else if( is_space(cr) && ( comparison_type_ & IGNORE_SPACE ) ) 
00113                 {
00114                         return true;
00115                 }
00116                 else 
00117                 {
00118                         return false;
00119                 }
00120         }
00121 
00122 };
00123 
00124 
00125 template< typename E >
00126 unsigned long basic_pattern_parser<E>::parse( const E *buf, const unsigned long buf_length )
00127 {
00128         prepare_for_parsing();
00129         typename string_type::iterator it = get_valid().begin();
00130 
00131         while( m_parsed_size < buf_length && 
00132                         it != get_valid().end() && 
00133                         compare( it, buf[m_parsed_size] ) )
00134         {
00135                 m_parsed_size++;
00136                 // it++;
00137         }
00138         if( it == get_valid().end() )
00139                 m_is_parsed = true;
00140         else 
00141                 m_parsed_size = 0;
00142 
00143         return m_parsed_size;
00144 }
00145 
00146 template< typename E >
00147 std::basic_istream<E>& basic_pattern_parser<E>::parse( std::basic_istream<E>& is )
00148 {
00149         prepare_for_parsing();
00150         typename string_type::iterator it = get_valid().begin();
00151 
00152         std::streampos str_pos = is.tellg();
00153         E input = 0;
00154         bool match = true;
00155 
00156         while( is.good()  &&  it != get_valid().end()  &&  match )
00157         {
00158                 m_parsed_size++;
00159                 is.read( &input, 1 );
00160                 match = compare( it, input );
00161         }
00162         if( it == get_valid().end() )
00163         {
00164                 m_is_parsed = true;
00165         }
00166         else 
00167         {
00168                 m_parsed_size = 0;
00169                 is.clear();
00170                 is.seekg( str_pos );
00171         }
00172         return is;
00173 }
00174 
00175 typedef basic_pattern_parser<char> pattern_parser;
00176 typedef basic_pattern_parser<wchar_t> wpattern_parser;
00177 
00178 };
00179 
00180 #endif

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