#ifndef _SYMBOL_HH #define _SYMBOL_HH #include //#include #include #include #include #include using namespace std; using __gnu_cxx::hash_map; using __gnu_cxx::hash; // Key comparison for the cstr_hash hash table struct eqstr { bool operator()(const char * s, const char* t) const { return strcmp(s,t)==0; } }; // Hash table for storing symbols typedef hash_map,eqstr> cstr_hash; // Symbol table. Provides access to symbols through their index or name. class Symbols { public: Symbols() { add("NULL"); }; ~Symbols(); void load(const char* filename); int operator[](const char* s) { return hash[s]; }; const char* operator[](int i) { return table[i]; }; void add(const char* c); int count() { return table.size(); }; private: std::vector table; cstr_hash hash; }; ////////////////////////////////////////////////////////////////////// /// Symbol class template. /** The template argument determines the symbol space. Each space is created with symbol "NULL" with indexed 0 already in. */ template class Symbol { public: /// Load the contents of the symbol table from file. static void define(const char *filename) { defs.load(filename); } /// Add symbol s. /** The string is duplicated. */ static Symbol add(const char* s) { defs.add(s); } /// Number of symbols. static int count() { return defs.count(); }; /// First symbol. static int first() { return 1; } /// Last symbol. static int last() { return defs.count()+1; } /// Last symbol. static int index(const char* s) { return defs[s]; } /// Just for tests. static void print(); /// 0-argument constructor, default value is 0 ("NULL"). Symbol() : val(0) {}; /// Constructing a symbol from its index. /** No check is performed. */ Symbol(int v) : val(v) {}; /// Constructing a symbol from its name (string to Symbol conversion). /** If s is not a symbol name, the value of 0 ("NULL") is assigned. */ Symbol(const char * s) : val(defs[s]) {}; /// Symbol to char* conversion. If symbol is invalid, NULL is returned. const char* str() const { return (val>=0 && val s=1; s; s++ ) ... s=0; while(++s) ... */ (operator int)() const { return val; }; Symbol operator++() {val++; return *this;} // bool operator<(Symbol& s) { return val < s.val; } private: static Symbols defs; int val; }; template void Symbol::print() { for(Symbol i=0; i Symbols Symbol::defs; template bool operator<(const Symbol& s, const Symbol& t) { return (int)s < (int)t; } #endif