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

  1. /*++
  2. /* NAME
  3. /*    tok_class 3
  4. /* SUMMARY
  5. /*    token classification
  6. /* PACKAGE
  7. /*    unproto
  8. /* SYNOPSIS
  9. /*    #include "token.h"
  10. /*
  11. /*    struct token *tok_class(skip)
  12. /*    int skip;
  13. /* DESCRIPTION
  14. /*    tok_class() collects a single and composite tokens, and
  15. /*    recognizes keywords.
  16. /*    At present, the only composite tokens are ()-delimited,
  17. /*    comma-separated lists.
  18. /*
  19. /*    The skip argument has the same meaning as with the tok_get()
  20. /*    function.
  21. /* DIAGNOSTICS
  22. /*    The code complains if input terminates in the middle of a list.
  23. /* BUGS
  24. /*    Does not preserve white space at the beginning of a list element
  25. /*    or after the end of a list.
  26. /* AUTHOR(S)
  27. /*    Wietse Venema
  28. /*    Eindhoven University of Technology
  29. /*    Department of Mathematics and Computer Science
  30. /*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  31. /* LAST MODIFICATION
  32. /*    91/11/30 21:10:28
  33. /* VERSION/RELEASE
  34. /*    1.3
  35. /*--*/
  36.  
  37. static char class_sccsid[] = "@(#) tok_class.c 1.3 91/11/30 21:10:28";
  38.  
  39. /* C library */
  40.  
  41. #include <stdio.h>
  42.  
  43. extern char *strcpy();
  44.  
  45. /* Application-specific stuff */
  46.  
  47. #include "error.h"
  48. #include "vstring.h"
  49. #include "token.h"
  50. #include "symbol.h"
  51.  
  52. static struct token *tok_list();
  53. static void tok_list_struct();
  54. static void tok_list_append();
  55.  
  56. /* tok_space_append - append trailing space except after list */
  57.  
  58. #define    tok_space_append(list,t) { \
  59.                     if (list == 0     /* leading space*/ \
  60.                     || list->tokno == TOK_LIST) \
  61.                     tok_free(t); \
  62.                     else \
  63.                     tok_list_append(list, t); \
  64.                 }
  65.  
  66. /* tok_class - discriminate single tokens, keywords, and composite tokens */
  67.  
  68. struct token *tok_class(skip)
  69. int     skip;
  70. {
  71.     register struct token *t;
  72.     register struct symbol *s;
  73.  
  74.     if (t = tok_get(skip)) {
  75.     switch (t->tokno) {
  76.     case '(':                /* beginning of list */
  77.         t = tok_list(t);
  78.         break;
  79.     case TOK_WORD:                /* look up keyword */
  80.         if (s = sym_find(t->vstr->str))
  81.         t->tokno = s->type;
  82.         break;
  83.     }
  84.     }
  85.     return (t);
  86. }
  87.  
  88. /* tok_list - collect ()-delimited, comma-separated list of tokens */
  89.  
  90. static struct token *tok_list(t)
  91. struct token *t;
  92. {
  93.     register struct token *list = tok_alloc();
  94.     char    filename[BUFSIZ];
  95.     int     lineno;
  96.  
  97.     /* Save context of '(' for diagnostics. */
  98.  
  99.     strcpy(filename, curr_path);
  100.     lineno = curr_line;
  101.  
  102.     list->tokno = TOK_LIST;
  103.     list->head = list->tail = t;
  104. #ifdef DEBUG
  105.     strcpy(list->vstr->str, "LIST");
  106. #endif
  107.  
  108.     for (;;) {
  109.     if ((t = tok_get(DO_WSPACE)) == 0) {    /* skip blanks */
  110.         error_where(0, filename, lineno, "unmatched '('");
  111.         return (list);            /* do not waste any data */
  112.     }
  113.     switch (t->tokno) {
  114.     case ')':                /* end of list */
  115.         tok_free(t);
  116.         return (list);
  117.     case '{':                /* struct/union type */
  118.         tok_list_struct(list->tail, t);
  119.         break;
  120.     case TOK_WSPACE:            /* preserve trailing blanks */
  121.         tok_space_append(list->tail->tail, t);    /* except after list */
  122.         break;
  123.     case '\n':                /* preserve line count */
  124.         tok_flush(t);
  125.         break;
  126.     case ',':                /* list separator */
  127.         tok_list_append(list, t);
  128.         break;
  129.     case '(':                /* beginning of list */
  130.         tok_list_append(list->tail, tok_list(t));
  131.         break;
  132.     default:                /* ordinary token */
  133.         tok_list_append(list->tail, t);
  134.         break;
  135.     }
  136.     }
  137. }
  138.  
  139. /* tok_list_struct - collect structured type info within list */
  140.  
  141. static void tok_list_struct(list, t)
  142. register struct token *list;
  143. register struct token *t;
  144. {
  145.     tok_list_append(list, t);
  146.  
  147.     while (t = tok_class(DO_WSPACE)) {
  148.     switch (t->tokno) {
  149.     case '\n':                /* preserve line count */
  150.         tok_flush(t);
  151.         break;
  152.     case TOK_WSPACE:            /* preserve trailing blanks */
  153.         tok_space_append(list->tail, t);    /* except after list */
  154.         break;
  155.     case '{':                /* recurse */
  156.         tok_list_struct(list, t);
  157.         break;
  158.     case '}':                /* done */
  159.         tok_list_append(list, t);
  160.         return;
  161.     default:                /* other */
  162.         tok_list_append(list, t);
  163.         break;
  164.     }
  165.     }
  166. }
  167.  
  168. /* tok_list_append - append data to list */
  169.  
  170. static void tok_list_append(h, t)
  171. struct token *h;
  172. struct token *t;
  173. {
  174.     if (h->head == 0) {
  175.     h->head = h->tail = t;
  176.     } else {
  177.     h->tail->next = t;
  178.     h->tail = t;
  179.     }
  180. }
  181.