00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef BRACKET_EXPRESSIONCOLLATING_SYMBOL_H
00021 #define BRACKET_EXPRESSIONCOLLATING_SYMBOL_H
00022
00023 namespace bracket_expression {
00024
00025 template< typename E >
00026 class collating_symbol
00027 {
00028 typedef typename grammar_to_parser::basic_parser<E>::parser_list
00029 parser_list;
00030
00031 class collating_base
00032 {
00033 protected:
00034 int m_size;
00035 public:
00036 int matched_size() { return m_size; }
00037 collating_base() : m_size(0) {};
00038 };
00039
00040 class opendot_coll_elem_single_dotclose : public collating_base
00041 {
00042 grammar_to_parser::basic_terminal<E, '['> m_open;
00043 grammar_to_parser::basic_terminal<E, '.'> m_left_dot;
00044 grammar_to_parser::basic_except_terminal<E,meta_char_choice<E> >
00045 m_coll_elem_single;
00046 grammar_to_parser::basic_terminal<E, '.'> m_right_dot;
00047 grammar_to_parser::basic_terminal<E, ']'> m_close;
00048 public:
00049
00050 void push_parsers( parser_list &l )
00051 {
00052 l.push_back(&m_open);
00053 l.push_back(&m_left_dot);
00054 l.push_back(&m_coll_elem_single);
00055 l.push_back(&m_right_dot);
00056 l.push_back(&m_close);
00057 }
00058 int compare( const E* buf, const unsigned long buf_length )
00059 {
00060 int ret = std::use_facet< std::collate<E> >(std::locale()).compare(
00061 buf,
00062 buf,
00063 m_coll_elem_single.get(),
00064 m_coll_elem_single.get() );
00065 if( ret == 0 )
00066 m_size =1;
00067 else
00068 m_size = 0;
00069 return ret;
00070 }
00071 };
00072
00073 class opendot_coll_elem_multi_dotclose : public collating_base
00074 {
00075 typedef std::ctype_base ctypebase;
00076 grammar_to_parser::basic_terminal<E, '['> m_open;
00077 grammar_to_parser::basic_terminal<E, '.'> m_left_dot;
00078 grammar_to_parser::basic_string_parser<E> m_coll_elem_multi;
00079
00080 grammar_to_parser::basic_terminal<E, '.'> m_right_dot;
00081 grammar_to_parser::basic_terminal<E, ']'> m_close;
00082 public:
00083 opendot_coll_elem_multi_dotclose() :
00084 collating_base(),
00085 m_coll_elem_multi('.', grammar_to_parser::basic_string_parser<E>::NONE) {};
00086
00087 void push_parsers( parser_list &l )
00088 {
00089 l.push_back(&m_open);
00090 l.push_back(&m_left_dot);
00091 l.push_back(&m_coll_elem_multi);
00092 l.push_back(&m_right_dot);
00093 l.push_back(&m_close);
00094 }
00095 int compare( const E* buf, const unsigned long buf_length )
00096 {
00097 unsigned long to_compare_length =
00098 collating_symbol<E>::get_symbol_len(buf,buf_length);
00099 std::basic_string<E> multichar = *(m_coll_elem_multi.get());
00100
00101 int ret = std::use_facet< std::collate<E> >(std::locale()).compare(
00102 buf,
00103 buf+to_compare_length,
00104 multichar.c_str(),
00105 multichar.c_str() + multichar.length() );
00106 m_size = to_compare_length;
00107 return ret;
00108 }
00109 };
00110
00111 class opendot_metachar_dotclose : public collating_base
00112 {
00113 grammar_to_parser::basic_terminal<E, '['> m_open;
00114 grammar_to_parser::basic_terminal<E, '.'> m_left_dot;
00115 grammar_to_parser::basic_choice<E,meta_char_choice<E> >
00116 m_meta_char;
00117 grammar_to_parser::basic_terminal<E, '.'> m_right_dot;
00118 grammar_to_parser::basic_terminal<E, ']'> m_close;
00119 public:
00120 void push_parsers( parser_list &l )
00121 {
00122 l.push_back(&m_open);
00123 l.push_back(&m_left_dot);
00124 l.push_back(&m_meta_char);
00125 l.push_back(&m_right_dot);
00126 l.push_back(&m_close);
00127 }
00128 int compare( const E* buf, const unsigned long buf_length )
00129 {
00130 int ret = m_meta_char->compare(buf,buf_length);
00131 m_size = 1;
00132 return ret;
00133 }
00134 };
00135 grammar_to_parser::basic_non_terminal<E, opendot_coll_elem_single_dotclose>
00136 m_coll_elem_single;
00137 grammar_to_parser::basic_non_terminal<E, opendot_coll_elem_multi_dotclose>
00138 m_multichar;
00139 grammar_to_parser::basic_non_terminal<E, opendot_metachar_dotclose>
00140 m_metachar;
00141 int m_size;
00142 public:
00143 collating_symbol() :
00144 m_coll_elem_single(),
00145 m_metachar(),
00146 m_multichar(),
00147 m_size(0) {};
00148
00149 void push_parsers( parser_list &l )
00150 {
00151 l.push_back(&m_multichar);
00152 l.push_back(&m_metachar);
00153 l.push_back(&m_coll_elem_single);
00154 }
00155
00156 int matched_size() { return m_size; }
00157 int compare( const E* buf, const unsigned long buf_length )
00158 {
00159 int ret = 0;
00160 if( m_coll_elem_single.is_parsed() )
00161 {
00162 ret = m_coll_elem_single->compare( buf, buf_length );
00163 m_size = m_coll_elem_single->matched_size();
00164 }
00165 else if( m_multichar.is_parsed() )
00166 {
00167 ret = m_multichar->compare( buf, buf_length );
00168 m_size = m_multichar->matched_size();
00169 }
00170 else
00171 {
00172 ret = m_metachar->compare( buf, buf_length );
00173 m_size = m_metachar->matched_size();
00174 }
00175 return ret;
00176 }
00177 static unsigned long get_symbol_len( const E* buf, const unsigned long buf_length );
00178 };
00179
00180
00181 unsigned long collating_symbol<char>::get_symbol_len( const char* buf,
00182 const unsigned long buf_length )
00183 {
00184
00185
00186
00187
00188
00189 return 1;
00190 int len = mblen( buf, buf_length );
00191 if( len < 0 )
00192 {
00193 len = 0;
00194 }
00195 return (unsigned long)len;
00196 }
00197
00198 unsigned long collating_symbol<wchar_t>::get_symbol_len( const wchar_t* buf,
00199 const unsigned long buf_length )
00200 {
00201
00202 if( buf_length > 0 )
00203 return 1;
00204 else
00205 return 0;
00206 }
00207
00208 };
00209
00210 #endif