home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / GCC / GERLIB_DEV08B.LHA / gerlib / libg++ / etc / ADT-examples / keyhash.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-12  |  4.7 KB  |  170 lines

  1. #ifdef amiga
  2. #include <use_standard_argc_argv.h>
  3. #endif
  4.  
  5. // Date: Tue, 20 Sep 88 01:03:21 -0700
  6. // From: "Douglas C. Schmidt" <schmidt%crimee.ics.uci.edu@PARIS.ICS.UCI.EDU>
  7. // 
  8. // 
  9. // The following is an Obstack-based program, which outputs all the GCC
  10. // reserved words in an input file redirected from cin 
  11. // In addition, I found a neat use for
  12. // derived types by defining a word-by-word input class that is based
  13. // upon the class Obstack.  Finally, there is the added bonus of seeing
  14. // how the O (1) time GCC perfect hash function recognizer from GCC 1.35
  15. // works; I've incorporated the relevant code in this short routine.
  16. // Feel free to fold, spindle, or mutilate this code.
  17. // 
  18.  
  19. #include <stream.h>
  20. #include <ctype.h>
  21. #include <Obstack.h>
  22.  
  23. #define NIL(TYPE) ((TYPE *)0)
  24.  
  25. class Word_Read : private Obstack
  26. {
  27. public:
  28.   Obstack::free; // Allow the derived type to inherit only this member function.
  29.  
  30.   // Make the default something reasonable, like 80 columns.
  31.   Word_Read (int Default_Len = 80): Obstack(Default_Len)
  32.     {
  33.       ;
  34.     }
  35.  
  36.   // A very rudimentary method for carving out the next word
  37.   // from the input.  Ignores most error conditions.  All non-
  38.   // words are skipped entirely.  A word is defined as a
  39.   // letter, followed by a sequence of letters, digits, and/or
  40.   // underbars `_'.
  41.  
  42.   char *operator ()(int& Len)
  43.     {
  44.       char c;
  45.       
  46.       while (cin.get (c) && !(isalpha (c) || c == '_'))
  47.         ;
  48.       
  49.       do
  50.         Obstack::grow (c);
  51.       while (cin.get (c) && (isalnum (c) || c == '_'));
  52.  
  53.       Len = Obstack::size ();
  54.       return cin.good () ? (char *)Obstack::finish (0) : 0;
  55.     }
  56.   
  57.   // Make the destructor print out something useful, like
  58.   // output a diagnostic.
  59.  
  60.   ~Word_Read ()
  61.     {
  62.       cout << "chunk_size = " << Obstack::chunk_size () << "\n";
  63.       cout << "size = " << Obstack::size () << "\n";
  64.       cout << "room = " << Obstack::room () << "\n";
  65.     }
  66. };
  67.  
  68. // Provides a nice example of the perfect hash function used to recognize
  69. // GCC reserved words in O(1) steps.
  70.  
  71. const int    MIN_WORD_SIZE = 2;
  72. const int    MAX_WORD_SIZE = 12;
  73. const int    MIN_KEY_SIZE  = 4;
  74. const int    MAX_KEY_SIZE  = 64;
  75.   
  76. class Lookup_Table
  77. {
  78. private:
  79.   static int Hash_Table[];
  80.  
  81.   static char *Reswords[];
  82.  
  83.   // And here it is....  Very simple, guaranteed to work!
  84.  
  85.   int Hash (char *Str,int Len)
  86.     {
  87.       switch (Len) 
  88.         {
  89.         default:
  90.         case 3:
  91.           Len += Hash_Table[Str[2]];
  92.         case 2:
  93.         case 1:
  94.           return Len + Hash_Table[Str[0]];
  95.         }
  96.     }
  97.   
  98. public:
  99.   
  100.   // Carries out the O (1) lookup for GCC reserved words!
  101.   int  operator () (char *Str,int Len);
  102. };
  103.  
  104. Lookup_Table::operator () (char *Str,int Len)
  105. {
  106.   if (Len <= MAX_WORD_SIZE && Len >= MIN_WORD_SIZE)
  107.     {
  108.       register int Key = Hash (Str,Len);
  109.  
  110.       if (Key >= MIN_KEY_SIZE && Key <= MAX_KEY_SIZE) 
  111.     if (*Reswords[Key] == *Str && !strcmp (Reswords[Key] + 1,Str + 1)) 
  112.       return 1;
  113.     }
  114.   return 0;   
  115. }
  116.  
  117. int  Lookup_Table::Hash_Table[] = 
  118.     {
  119.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  120.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  121.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  122.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  123.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  124.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  125.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  126.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  127.       64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
  128.       64,  64,  64,  64,  64,   1,  64,   9,  17,  15,
  129.       28,  19,  29,  15,  64,   2,  64,  64,  25,   4,
  130.       16,  22,  40,  64,  11,  23,   1,   1,  16,   2,
  131.       64,  64,   8,  64,  64,  64,  64,  64,
  132. };
  133.  
  134. char * Lookup_Table::Reswords[] =
  135. {
  136.       "", "", "", "", "if", "", "int", "", "union", "while", "__typeof", 
  137.       "__inline", "__typeof__", "__inline__", "auto", "__asm", "asm", "__asm__",
  138.       "return", "__alignof", "goto", "__alignof__", "void", "__const",
  139.       "enum", "__const__", "extern", "__volatile", "char", "__volatile__",
  140.       "do", "switch", "unsigned", "inline", "register", "double", "const",
  141.       "sizeof", "static", "continue", "struct", "break", "case", "for",
  142.       "signed", "long", "else", "typeof", "typedef", "volatile", "short",
  143.       "", "", "", "", "", "float", "", "", "", "", "", "", "", "default",
  144. };
  145.  
  146.  
  147. static void Store_Buf (char *Buf)
  148.   cout << "Storing reserved word " << Buf << "\n";
  149.   //  Just kidding!  But you get the idea....
  150. }
  151.  
  152. main (int argc, char *argv[])
  153. {
  154.   Word_Read    Get_Next_Word;
  155.   Lookup_Table Is_Reserved_Word;
  156.   char *Buf;
  157.   int   Len;
  158.   
  159.   while (Buf = Get_Next_Word (Len)) 
  160.     if (Is_Reserved_Word (Buf,Len)) 
  161.       Store_Buf (Buf);          // Keep reserved words
  162.     else                        
  163.       Get_Next_Word.free (Buf); // Discard non-reserved words
  164.   
  165.   return 0;
  166. }
  167.  
  168.  
  169.