00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef _KROVETZ_STEMMER_H_
00016 #define _KROVETZ_STEMMER_H_
00017 #include <cstring>
00018 #ifdef WIN32
00019 #include <hash_map>
00020 #else
00021
00022 #ifndef HAVE_GCC_VERSION
00023 #define HAVE_GCC_VERSION(MAJOR, MINOR) \
00024 (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
00025 #endif
00026 #if HAVE_GCC_VERSION(4,3)
00027
00028 #include <tr1/unordered_map>
00029 #else
00030 #include <ext/hash_map>
00031 #endif
00032
00033 using namespace __gnu_cxx;
00034 #endif
00035 #include "indri/Mutex.hpp"
00036 #include "indri/ScopedLock.hpp"
00037
00038 namespace indri
00039 {
00040 namespace parse
00041 {
00042 class KrovetzStemmer
00043 {
00044 public:
00045 KrovetzStemmer();
00046 ~KrovetzStemmer();
00048 static const int MAX_WORD_LENGTH=25;
00060 char * kstem_stemmer(char *term);
00072 int kstem_stem_tobuffer(char *term, char *buffer);
00080 void kstem_add_table_entry(const char* variant, const char* word,
00081 bool exc=false);
00082 private:
00084 indri::thread::Mutex _stemLock;
00086 typedef struct dictEntry {
00088 bool exception;
00090 const char *root;
00091 } dictEntry;
00093 typedef struct cacheEntry {
00095 char flag;
00097 char word1[MAX_WORD_LENGTH];
00099 char stem1[MAX_WORD_LENGTH];
00101 char word2[MAX_WORD_LENGTH];
00103 char stem2[MAX_WORD_LENGTH];
00104 } cacheEntry;
00105
00106
00107 bool ends(const char *s, int sufflen);
00108 void setsuff(const char *str, int length);
00109 dictEntry *getdep(char *word);
00110 bool lookup(char *word);
00111 bool cons(int i);
00112 bool vowelinstem();
00113 bool vowel(int i);
00114 bool doublec(int i);
00115 void plural();
00116 void past_tense();
00117 void aspect();
00118 void ion_endings();
00119 void er_and_or_endings ();
00120 void ly_endings ();
00121 void al_endings() ;
00122 void ive_endings() ;
00123 void ize_endings() ;
00124 void ment_endings() ;
00125 void ity_endings() ;
00126 void ble_endings() ;
00127 void ness_endings() ;
00128 void ism_endings();
00129 void ic_endings();
00130 void ncy_endings();
00131 void nce_endings();
00132
00133 void loadTables();
00134 #ifdef WIN32
00135 struct ltstr {
00136 bool operator()(const char* s1, const char* s2) const {
00137 return strcmp(s1, s2) < 0;
00138 }
00139 };
00140
00141
00142 typedef stdext::hash_map<const char *, dictEntry, stdext::hash_compare<const char *, ltstr> > dictTable;
00143 #else
00144 struct eqstr {
00145 bool operator()(const char* s1, const char* s2) const {
00146 return strcmp(s1, s2) == 0;
00147 }
00148 };
00149 #if HAVE_GCC_VERSION(4,3)
00150 typedef std::tr1::unordered_map<const char *, dictEntry, std::tr1::hash<const char *>, eqstr> dictTable;
00151 #else
00152 typedef hash_map<const char *, dictEntry, hash<const char *>, eqstr> dictTable;
00153 #endif
00154 #endif
00155 dictTable dictEntries;
00156
00157
00158 cacheEntry *stemCache;
00159
00160 int stemhtsize;
00161
00162
00163 int k;
00164
00165 int j;
00166
00167 char *word;
00168
00169 char stem[MAX_WORD_LENGTH];
00170 };
00171 }
00172 }
00173 #endif