home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume26 / unproto / part01 / symbol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-07  |  3.4 KB  |  162 lines

  1. /*++
  2. /* NAME
  3. /*    symbol 3
  4. /* SUMMARY
  5. /*    rudimentary symbol table package
  6. /* SYNOPSIS
  7. /*    #include "symbol.h"
  8. /*
  9. /*    void sym_init()
  10. /*
  11. /*    void sym_enter(name, type)
  12. /*    char *name;
  13. /*    int type;
  14. /*
  15. /*    struct symbol *sym_find(name)
  16. /*    char *name;
  17. /* DESCRIPTION
  18. /*    This is a rudimentary symbol-table package, just enough to
  19. /*    keep track of a couple of C keywords.
  20. /*
  21. /*    sym_init() primes the table with C keywords. At present, most of
  22. /*    the keywords that have to do with types are left out.
  23. /*    We need a different strategy to detect type definitions because
  24. /*    we do not keep track of typedef names.
  25. /*
  26. /*    sym_enter() adds an entry to the symbol table.
  27. /*
  28. /*    sym_find() locates a symbol table entry (it returns 0 if
  29. /*    it is not found).
  30. /* AUTHOR(S)
  31. /*    Wietse Venema
  32. /*    Eindhoven University of Technology
  33. /*    Department of Mathematics and Computer Science
  34. /*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  35. /* LAST MODIFICATION
  36. /*    91/11/30 21:10:33
  37. /* VERSION/RELEASE
  38. /*    1.2
  39. /*--*/
  40.  
  41. static char symbol_sccsid[] = "@(#) symbol.c 1.2 91/11/30 21:10:33";
  42.  
  43. /* C library */
  44.  
  45. extern char *strcpy();
  46. extern char *malloc();
  47.  
  48. /* Application-specific stuff */
  49.  
  50. #include "error.h"
  51. #include "token.h"
  52. #include "symbol.h"
  53.  
  54. #define    SYM_TABSIZE    20
  55.  
  56. static struct symbol *sym_tab[SYM_TABSIZE] = {0,};
  57.  
  58. /* More string stuff. Maybe it should go to an #include file. */
  59.  
  60. #define    STREQ(x,y)    (*(x) == *(y) && strcmp((x),(y)) == 0)
  61.  
  62. /* hash - hash a string; original author: P. J. Weinberger at Bell Labs. */
  63.  
  64. static unsigned hash(s, size)
  65. register char *s;
  66. unsigned size;
  67. {
  68.     register unsigned long h = 0;
  69.     register unsigned long g;
  70.  
  71.     /*
  72.      * For a performance comparison with the hash function presented in K&R,
  73.      * first edition, see the "Dragon" book by Aho, Sethi and Ullman.
  74.      */
  75.  
  76.     while (*s) {
  77.     h = (h << 4) + *s++;
  78.     if (g = (h & 0xf0000000)) {
  79.         h ^= (g >> 24);
  80.         h ^= g;
  81.     }
  82.     }
  83.     return (h % size);
  84. }
  85.  
  86. /* sym_enter - enter symbol into table */
  87.  
  88. void    sym_enter(name, type)
  89. char   *name;
  90. int     type;
  91. {
  92.     struct symbol *s;
  93.     int     where;
  94.  
  95.     if ((s = (struct symbol *) malloc(sizeof(*s))) == 0
  96.     || (s->name = malloc(strlen(name) + 1)) == 0)
  97.     error(1, "out of memory");
  98.     (void) strcpy(s->name, name);
  99.     s->type = type;
  100.  
  101.     where = hash(name, SYM_TABSIZE);
  102.     s->next = sym_tab[where];
  103.     sym_tab[where] = s;
  104. }
  105.  
  106. /* sym_find - locate symbol definition */
  107.  
  108. struct symbol *sym_find(name)
  109. register char *name;
  110. {
  111.     register struct symbol *s;
  112.  
  113.     /*
  114.      * This function is called for almost every "word" token, so it better be
  115.      * fast.
  116.      */
  117.  
  118.     for (s = sym_tab[hash(name, SYM_TABSIZE)]; s; s = s->next)
  119.     if (STREQ(name, s->name))
  120.         return (s);
  121.     return (0);
  122. }
  123.  
  124.  /*
  125.   * Initialization data for symbol table. We do not enter keywords for types.
  126.   * We use a different strategy to detect type declarations because we do not
  127.   * keep track of typedef names.
  128.   */
  129.  
  130. struct sym {
  131.     char   *name;
  132.     int     tokno;
  133. };
  134.  
  135. static struct sym syms[] = {
  136.     "if", TOK_CONTROL,
  137.     "else", TOK_CONTROL,
  138.     "while", TOK_CONTROL,
  139.     "do", TOK_CONTROL,
  140.     "switch", TOK_CONTROL,
  141.     "case", TOK_CONTROL,
  142.     "default", TOK_CONTROL,
  143.     "return", TOK_CONTROL,
  144.     "continue", TOK_CONTROL,
  145.     "break", TOK_CONTROL,
  146.     "goto", TOK_CONTROL,
  147.     "struct", TOK_COMPOSITE,
  148.     "union", TOK_COMPOSITE,
  149.     0,
  150. };
  151.  
  152. /* sym_init - enter known keywords into symbol table */
  153.  
  154. void    sym_init()
  155. {
  156.     register struct sym *p;
  157.  
  158.     for (p = syms; p->name; p++)
  159.     sym_enter(p->name, p->tokno);
  160. }
  161.  
  162.