|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T k
Length: 4762 (0x129a) Types: TextFile Names: »keyhash.cc«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z« └─⟦23757c458⟧ └─⟦this⟧ »libg++/etc/keyhash.cc«
// Date: Tue, 20 Sep 88 01:03:21 -0700 // From: "Douglas C. Schmidt" <schmidt%crimee.ics.uci.edu@PARIS.ICS.UCI.EDU> // // // The following is an Obstack-based program, which outputs all the GCC // reserved words in an input file redirected from cin // In addition, I found a neat use for // derived types by defining a word-by-word input class that is based // upon the class Obstack. Finally, there is the added bonus of seeing // how the O (1) time GCC perfect hash function recognizer from GCC 1.35 // works; I've incorporated the relevant code in this short routine. // Feel free to fold, spindle, or mutilate this code. // #include <stream.h> #include <ctype.h> #include <Obstack.h> #define NIL(TYPE) ((TYPE *)0) class Word_Read : private Obstack { public: Obstack::free; // Allow the derived type to inherit only this member function. // Make the default something reasonable, like 80 columns. Word_Read (int Default_Len = 80): (Default_Len) { ; } // A very rudimentary method for carving out the next word // from the input. Ignores most error conditions. All non- // words are skipped entirely. A word is defined as a // letter, followed by a sequence of letters, digits, and/or // underbars `_'. char *operator ()(int& Len = 0) { char c; while (cin.get (c) && !(isalpha (c) || c == '_')) ; do Obstack::grow (c); while (cin.get (c) && (isalnum (c) || c == '_')); Len = Obstack::size (); return cin.good () ? Obstack::finish (0) : 0; } // Make the destructor print out something useful, like // output a diagnostic. ~Word_Read () { cout << "chunk_size = " << Obstack::chunk_size () << "\n"; cout << "size = " << Obstack::size () << "\n"; cout << "room = " << Obstack::room () << "\n"; } }; // Provides a nice example of the perfect hash function used to recognize // GCC reserved words in O(1) steps. class Lookup_Table { private: const int MIN_WORD_SIZE = 2; const int MAX_WORD_SIZE = 12; const int MIN_KEY_SIZE = 4; const int MAX_KEY_SIZE = 64; static int Hash_Table[] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1, 64, 9, 17, 15, 28, 19, 29, 15, 64, 2, 64, 64, 25, 4, 16, 22, 40, 64, 11, 23, 1, 1, 16, 2, 64, 64, 8, 64, 64, 64, 64, 64, }; static char *Reswords[] = { "", "", "", "", "if", "", "int", "", "union", "while", "__typeof", "__inline", "__typeof__", "__inline__", "auto", "__asm", "asm", "__asm__", "return", "__alignof", "goto", "__alignof__", "void", "__const", "enum", "__const__", "extern", "__volatile", "char", "__volatile__", "do", "switch", "unsigned", "inline", "register", "double", "const", "sizeof", "static", "continue", "struct", "break", "case", "for", "signed", "long", "else", "typeof", "typedef", "volatile", "short", "", "", "", "", "", "float", "", "", "", "", "", "", "", "default", }; // And here it is.... Very simple, guaranteed to work! int Hash (char *Str,int Len) { switch (Len) { default: case 3: Len += Hash_Table[Str[2]]; case 2: case 1: return Len + Hash_Table[Str[0]]; } } public: // Carries out the O (1) lookup for GCC reserved words! int operator () (char *Str,int Len) { if (Len <= MAX_WORD_SIZE && Len >= MIN_WORD_SIZE) { register int Key = Hash (Str,Len); if (Key >= MIN_KEY_SIZE && Key <= MAX_KEY_SIZE) if (*Reswords[Key] == *Str && !strcmp (Reswords[Key] + 1,Str + 1)) return 1; } return 0; } }; static void Store_Buf (char *Buf) { cout << "Storing reserved word " << Buf << "\n"; // Just kidding! But you get the idea.... } main (int argc, char *argv[]) { Word_Read Get_Next_Word; Lookup_Table Is_Reserved_Word; char *Buf; int Len; while (Buf = Get_Next_Word (Len)) if (Is_Reserved_Word (Buf,Len)) Store_Buf (Buf); // Keep reserved words else Get_Next_Word.free (Buf); // Discard non-reserved words return 0; }