home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / rpc2 / part10 / rpc / rpcgen / rpc_scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.7 KB  |  358 lines

  1. #ifndef lint 
  2. static char sccsid[] = "@(#)rpc_scan.c 1.1 86/03/26 (C) 1986 SMI";
  3. #endif
  4.  
  5. /*
  6.  * rpc_scan.c, Scanner for the RPC protocol compiler
  7.  * Copyright (C) 1986, Sun Microsystems, Inc.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <strings.h>
  13. #include "rpc_scan.h"
  14. #include "rpc_util.h"
  15.  
  16. #define commentstart(p)    (*(p) == '/' && *((p) + 1) == '*')
  17. #define commentend(p)    (*(p) == '*' && *((p) + 1) == '/') 
  18.  
  19. static int pushed = 0;            /* is a token pushed */
  20. static token lasttok;            /* last token, if pushed */
  21. static int scan_print;            /* print out directives? */
  22.  
  23. /*
  24.  * turn printing on or off
  25.  */
  26. void
  27. scanprint(sw) 
  28.     int sw; 
  29. {
  30.     scan_print = sw;
  31. }
  32.  
  33.  
  34. /*
  35.  * scan expecting 1 given token
  36.  */
  37. void
  38. scan(expect,tokp)
  39.     tok_kind expect;
  40.     token *tokp;
  41. {
  42.     get_token(tokp);
  43.     if (tokp->kind != expect) {
  44.         expected1(expect);
  45.     }
  46. }
  47.  
  48. /*
  49.  * scan expecting 2 given tokens
  50.  */
  51. void
  52. scan2(expect1,expect2,tokp)
  53.     tok_kind expect1;
  54.     tok_kind expect2;
  55.     token *tokp;
  56. {
  57.     get_token(tokp);
  58.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  59.         expected2(expect1,expect2);
  60.     }
  61. }
  62.  
  63. /*
  64.  * scan expecting 3 given token
  65.  */
  66. void
  67. scan3(expect1,expect2,expect3,tokp)
  68.     tok_kind expect1;
  69.     tok_kind expect2;
  70.     tok_kind expect3;
  71.     token *tokp;
  72. {
  73.     get_token(tokp);
  74.     if (tokp->kind != expect1 && tokp->kind != expect2 
  75.             && tokp->kind != expect3) {
  76.         expected3(expect1,expect2,expect3);
  77.     }
  78. }
  79.  
  80.  
  81. /*
  82.  * scan expecting a constant, possibly symbolic
  83.  */
  84. void
  85. scan_num(tokp)
  86.     token *tokp;
  87. {
  88.     get_token(tokp);
  89.     switch (tokp->kind) {
  90.     case TOK_CONST:    
  91.     case TOK_IDENT:
  92.         break;    
  93.     default:
  94.         error("constant or identifier expected");
  95.     }
  96. }
  97.  
  98.  
  99. /*
  100.  * Peek at the next token
  101.  */
  102. void
  103. peek(tokp)
  104.     token *tokp;
  105. {
  106.     get_token(tokp);
  107.     unget_token(tokp);
  108. }
  109.  
  110.  
  111. /*
  112.  * Peek at the next token and
  113.  * scan it if it matches what you expect
  114.  */
  115. int
  116. peekscan(expect,tokp)
  117.     tok_kind expect;
  118.     token *tokp;
  119. {
  120.     peek(tokp);
  121.     if (tokp->kind == expect) {
  122.         get_token(tokp);
  123.         return(1);
  124.     }
  125.     return(0);
  126. }
  127.  
  128.  
  129.  
  130. /*
  131.  * Get the next token, printing out any directive that
  132.  * are encountered.
  133.  */
  134. void
  135. get_token(tokp)
  136.     token *tokp;
  137. {
  138.  
  139.     if (pushed) {
  140.         pushed = 0;
  141.         *tokp = lasttok;
  142.         return;
  143.     }
  144.     for (;;) {    
  145.         if (*where == 0) {
  146.             if (! fgets(curline,MAXLINESIZE,fin)) {
  147.                 tokp->kind = TOK_EOF;
  148.                 *where = 0;
  149.                 return;
  150.             }
  151.             where = curline;
  152.             linenum++;
  153.         } else if (isspace(*where)) {
  154.             whitespace();
  155.         } else if (commentstart(where)) {
  156.             decomment();
  157.         } else if (directive(where)) {
  158.             printdirective(where);
  159.             *where = 0;
  160.         } else {
  161.             break;
  162.         }
  163.     }
  164.     /* 
  165.      * 'where' is not whitespace, comment, or directive
  166.      * Must be a token!
  167.      */
  168.     switch (*where) {
  169.     case ':':    tokp->kind = TOK_COLON; where++; break;    
  170.     case ';':    tokp->kind = TOK_SEMICOLON; where++; break;
  171.     case ',':    tokp->kind = TOK_COMMA; where++; break;
  172.     case '=':    tokp->kind = TOK_EQUAL; where++; break;
  173.     case '*':    tokp->kind = TOK_STAR; where++; break;
  174.     case '[':    tokp->kind = TOK_LBRACKET; where++; break;
  175.     case ']':    tokp->kind = TOK_RBRACKET; where++; break;
  176.     case '{':    tokp->kind = TOK_LBRACE; where++; break;
  177.     case '}':    tokp->kind = TOK_RBRACE; where++; break;
  178.     case '(':    tokp->kind = TOK_LPAREN; where++; break;
  179.     case ')':    tokp->kind = TOK_RPAREN; where++; break;
  180.  
  181.     case '0':      
  182.     case '1': 
  183.     case '2':
  184.     case '3':
  185.     case '4':
  186.     case '5':
  187.     case '6':
  188.     case '7':
  189.     case '8':
  190.     case '9':
  191.         tokp->kind = TOK_CONST; 
  192.         findconst(&where,&tokp->str);
  193.         break;
  194.  
  195.  
  196.     default:
  197.         if ( ! (isalpha(*where) || *where == '_')) {
  198.             char buf[100];
  199.             char *p;
  200.  
  201.             sprintf(buf,"illegal character in file: ");
  202.             p = buf + strlen(buf);
  203.             if (isprint(*where)) {
  204.                 sprintf(p,"%c",*where);    
  205.             } else {
  206.                 sprintf(p,"%d",*where);
  207.             }
  208.             error(buf);
  209.         }
  210.         findkind(&where,tokp);
  211.         break;
  212.     }
  213. }
  214.  
  215.  
  216.  
  217. static
  218. unget_token(tokp)
  219.     token *tokp;
  220. {
  221.     lasttok = *tokp;
  222.     pushed = 1;
  223. }
  224.  
  225.  
  226. static
  227. findconst(str,val)
  228.     char **str;
  229.     char **val;
  230. {
  231.     char *p;
  232.     int size;
  233.  
  234.     p = *str;
  235.     do {
  236.         *p++;
  237.     } while (isdigit(*p));
  238.     size = p - *str;
  239.     *val = alloc(size + 1);
  240.     strncpy(*val,*str,size);
  241.     (*val)[size] = 0;
  242.     *str = p;
  243. }
  244.  
  245.  
  246.  
  247. static token symbols[] = {
  248.     { TOK_UNION,    "union" },
  249.     { TOK_SWITCH,    "switch" }, 
  250.     { TOK_CASE,    "case" },
  251.     { TOK_DEFAULT,    "default" },
  252.     { TOK_STRUCT,        "struct" },
  253.     { TOK_TYPEDEF,    "typedef" },
  254.     { TOK_ENUM,    "enum" },
  255.     { TOK_ARRAY,    "array" },
  256.     { TOK_OPAQUE,    "opaque" },
  257.     { TOK_BOOL,    "bool" },
  258.     { TOK_VOID,    "void" },
  259.     { TOK_CHAR,    "char" },
  260.     { TOK_INT,    "int" },
  261.     { TOK_UNSIGNED,    "unsigned" },
  262.     { TOK_SHORT,    "short" },
  263.     { TOK_LONG,    "long" },
  264.     { TOK_FLOAT,    "float" },
  265.     { TOK_DOUBLE,    "double" },
  266.     { TOK_STRING,    "string" },
  267.     { TOK_PROGRAM,    "program" },
  268.     { TOK_VERSION,    "version" },
  269.     { TOK_EOF,    "??????"},
  270. };
  271.  
  272.  
  273. static
  274. findkind(mark,tokp)
  275.     char **mark;
  276.     token *tokp;
  277. {
  278.  
  279.     int len;
  280.     token *s;
  281.     char *str;
  282.  
  283.     str = *mark;
  284.     for (s = symbols; s->kind != TOK_EOF; s++) {
  285.         len = strlen(s->str);
  286.         if (strncmp(str,s->str,len) == 0) {
  287.             if (!isalnum(str[len]) && str[len] != '_') {
  288.                 tokp->kind = s->kind;
  289.                 tokp->str = s->str;
  290.                 *mark = str + len;
  291.                 return;    
  292.             }
  293.         }
  294.     }
  295.     tokp->kind = TOK_IDENT;
  296.     for (len = 0; isalnum(str[len]) || str[len] == '_'; len++)
  297.         ;
  298.     tokp->str = alloc(len+1);
  299.     strncpy(tokp->str,str,len);
  300.     tokp->str[len] = 0;
  301.     *mark = str + len;
  302. }
  303.  
  304. static
  305. whitespace()
  306. {
  307.     while (isspace(*where))
  308.         where++;
  309. }
  310.  
  311. static
  312. decomment()
  313. {
  314.     for (where += 2; ! commentend(where) ; where++) {
  315.         if (*where == 0) {
  316.             if (! fgets(curline,MAXLINESIZE,fin)) {
  317.                 error("unterminated comment");
  318.             }
  319.             linenum++;
  320.             where = curline - 1;
  321.         }
  322.     }
  323.     where += 2;
  324. }
  325.  
  326.  
  327. static
  328. directive(line)
  329.     char *line;
  330. {
  331.     return(line == curline && *line == '#');
  332. }
  333.  
  334. static
  335. printdirective(line)
  336.     char *line;
  337. {
  338.     char *s;
  339.  
  340.     for (s = line + strlen(line) - 1; s >= line; s--) {
  341.         if (commentend(s)) {
  342.             break;    
  343.         } else if (commentstart(s)) {
  344.             where = s;
  345.             *where++ = '\n';
  346.             *where = 0;    
  347.             if (scan_print) {
  348.                 fprintf(fout,line);
  349.             }
  350.             decomment();
  351.             return;
  352.         } 
  353.     }
  354.     if (scan_print) {
  355.         fprintf(fout,line);
  356.     }
  357. }                
  358.