#include "symtab.h" #include // numeric_limits #include #include //--------------------------------------------------------------------------- using namespace UTT; SymbolTable::SymbolTable(int n, int (*h)(const char*,int), const char* filename) : _mx(n), _cnt(0), hash(h) { _sz=first(n); _key=new char*[_sz]; _defind=new int[_sz]; _hashind=new int[_sz]; _def=new char*[_mx]; for(int i=0; i<_sz; i++) _key[i]=NULL; if(filename) add_from_file(filename); } //--------------------------------------------------------------------------- SymbolTable::SymbolTable(int n, const char* filename) : _mx(n), _cnt(0), hash(hash1) { _sz=first(n); _key=new char*[_sz]; _defind=new int[_sz]; _hashind=new int[_sz]; _def=new char*[_mx]; for(int i=0; i<_sz; ++i) _key[i]=NULL; if(filename) add_from_file(filename); } //--------------------------------------------------------------------------- SymbolTable::~SymbolTable() { clear(); delete[] _key; delete[] _defind; delete[] _hashind; delete[] _def; } //--------------------------------------------------------------------------- void SymbolTable::clear() { for(int i=0; i<_sz; ++i) if(_key[i]) free(_key[i]); } //--------------------------------------------------------------------------- bool SymbolTable::add_from_file(const char* filename) { FILE* in=fopen(filename,"r"); char buf[MAXKEYLEN+1]; if(in) while(fscanf(in,"%s",buf)==1) { if(strlen(buf)==MAXKEYLEN || add(buf)<0) return false; } return true; } //--------------------------------------------------------------------------- int SymbolTable::add(const char* s) { if(_cnt<_mx) { int ind=hash(s,_sz); while(_key[ind]) if(strcmp(_key[ind],s)) ind=++ind%_sz; else return _defind[ind]; _key[ind]=strdup(s); _defind[ind]=_cnt; _hashind[_cnt]=ind; _def[_cnt]=_key[ind]; _cnt++; return _cnt-1; } else return -1; } //--------------------------------------------------------------------------- int SymbolTable::operator[](const char* s) { int ind=hash(s,_sz); while(_key[ind]) if(strcmp(_key[ind],s)==0) return _defind[ind]; else ind=++ind % _sz; return -1; } //--------------------------------------------------------------------------- int SymbolTable::first(unsigned int n) { int fi=n; int bound=(n/2 < MAXKEYLEN)? n/2 : MAXKEYLEN; bool found; do { found=true; if(fi++ == std::numeric_limits::max) return -1; for(int i=2; i=4) return abs((*((int*)(s+(l/2-2)))+(int)(*s * s[l-1])) % _sz); else { int i=0; strcpy((char*)&i,s); return abs((i+(int)(*s * s[l-1])) % _sz); } } //--------------------------------------------------------------------------- int hash2(const char* s, int _sz) { int l=strlen(s); if(l>=6) { unsigned int i1,i2,i3; strncpy((char*)&i1,s,sizeof(int)); strncpy((char*)&i2,s+(l/2-2),sizeof(int)); strncpy((char*)&i3,s+(l-4),sizeof(int)); return abs((i1+i2+i3) % _sz); } else { int i=0; strncpy((char*)&i,s,sizeof(int)); return abs((i+(int)(*s * s[l-1])) % _sz); } } //---------------------------------------------------------------------------