00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00075
00076 std::basic_stringstream<E> ss;
00077 ss << pattern;
00078 return ss.str();
00079
00080
00081
00082
00083
00084
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
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
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