home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.lbl.gov / 2014.05.ftp.ee.lbl.gov.tar / ftp.ee.lbl.gov / bmd-1.0beta.tar.Z / bmd-1.0beta.tar / bmd-1.0beta / app / omtd / readline.c < prev    next >
C/C++ Source or Header  |  1991-02-17  |  7KB  |  363 lines

  1. /*
  2.  * Copyright (c) 1990 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Lawrence Berkeley Laboratory,
  11.  * Berkeley, CA.  The name of the University may not be used to
  12.  * endorse or promote products derived from this software without
  13.  * specific prior written permission.
  14.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  15.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  16.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17.  */
  18. /*
  19.  * File: lexical.c
  20.  *
  21.  * String table routines for Prescript compiler.
  22.  *     Van Jacobson, January, 1988
  23.  */
  24.  
  25. /*
  26.  * Copyright (c) 1988 Regents of the University of California.
  27.  * All rights reserved.
  28.  *
  29.  * Redistribution and use in source and binary forms are permitted
  30.  * provided that the above copyright notice and this paragraph are
  31.  * duplicated in all such forms and that any documentation,
  32.  * advertising materials, and other materials related to such
  33.  * distribution and use acknowledge that the software was developed
  34.  * by the University of California, Lawrence Berkeley Laboratory,
  35.  * Berkeley, CA.  The name of the University may not be used to
  36.  * endorse or promote products derived from this software without
  37.  * specific prior written permission.
  38.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  39.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  40.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  41.  */
  42.  
  43. #ifndef lint
  44. static char rcsid[] =
  45.     "@(#) $Header: readline.c,v 1.3 91/01/13 20:14:14 mccanne Locked $ (LBL)";
  46. static char copyright[] =
  47.     "Copyright (c) 1988, Regents of the University of California";
  48. #endif lint
  49.  
  50. #include <stdio.h>
  51. #include <sys/types.h>
  52.  
  53. #include "readline.h"
  54.  
  55. extern char *malloc();
  56. extern char *realloc();
  57.  
  58. #define MODULUS 16001
  59.  
  60. static u_char *idTable[MODULUS];
  61. static u_char *stringTable;
  62. static u_char *stNext;
  63. static int stSize = 2048;
  64. static int stLeft = 2048;
  65.  
  66. rl_init()
  67. {
  68.     /* get the initial string table space */
  69.  
  70.     stNext = stringTable = (u_char *)malloc (stSize);
  71.     if (stringTable == 0)
  72.         error("out of memory");
  73. }
  74.  
  75. /* "hashpjw" from Aho, Sethi & Ullman, p.436 */
  76. static int
  77. hash(str, len)
  78.     register u_char *str;
  79.     register int len;
  80. {
  81.     register unsigned int h = 0, g;
  82.  
  83.     while (--len >= 0) {
  84.         h = (h << 4) + *str++;
  85.         if (g = h & 0xf0000000) {
  86.             h = h ^ (g >> 24);
  87.             h = h ^ g;
  88.         }
  89.     }
  90.     return (h % MODULUS);
  91. }
  92.  
  93. static char *
  94. EnterString(str, len)
  95.     u_char *str;
  96.     int len;
  97. {
  98.     register int h = hash (str, len);
  99.  
  100.     while (idTable[h]) {
  101.         if (bcmp(str, idTable[h], len) == 0)
  102.             return (char *)idTable[h];
  103.         h = ++h % MODULUS;
  104.     }
  105.     /* didn't find string in table - add it */
  106.     if ((stLeft -= len + 1) <= 0) {
  107.         register u_char *cp = stringTable;
  108.  
  109.         stLeft += stSize;
  110.         stSize *= 2;
  111.  
  112.         stringTable = (u_char *)realloc(cp, stSize);
  113.  
  114.         if (stringTable == 0)
  115.             error("out of memory");
  116.  
  117.         if (cp != stringTable) {
  118.             /*
  119.              * realloc moved our table -- fix up the
  120.              * pointers in idTable.
  121.              */
  122.             register int i = MODULUS;
  123.             register int j = stringTable - cp;
  124.  
  125.             stNext += j;
  126.             for (i = 0; i < MODULUS; i++)
  127.                 if (idTable[i])
  128.                     idTable[i] += j;
  129.         }
  130.     }
  131.     idTable[h] = stNext;
  132.     strncpy(stNext, str, len);
  133.     stNext += len;
  134.     *stNext++ = 0;
  135.     return (char *)idTable[h];
  136.  
  137. }
  138.  
  139. #define MAXLINE 512
  140. #define MAXTOKENS 256
  141.  
  142. struct token tokens[MAXTOKENS];
  143. struct token *tok_vector[MAXTOKENS];
  144.  
  145. static int curtoken;
  146.  
  147. #define RESET_TOKEN curtoken = 0
  148. #define NEXT_TOKEN &tokens[curtoken++]
  149.  
  150. char *
  151. rl_id(p, cp)
  152.     struct token **p;
  153.     char *cp;
  154. {
  155.     struct token *tp = NEXT_TOKEN;
  156.     char *str = cp;
  157.  
  158.     while (isalpha(*cp) || *cp == '_' || isdigit(*cp))
  159.         ++cp;
  160.     tp->t_id = TK_IDENT;
  161.     tp->t_str = EnterString(str, cp - str);
  162.     *p = tp;
  163.  
  164.     return cp;
  165. }
  166.  
  167. char *
  168. intern(s)
  169.     char *s;
  170. {
  171.     return EnterString(s, strlen(s));
  172. }
  173.  
  174. /* Hex digit to integer. */
  175. static inline int
  176. xdtoi(c)
  177. {
  178.     if (isdigit(c))
  179.         return c - '0';
  180.     else if (islower(c))
  181.         return c - 'a' + 10;
  182.     else
  183.         return c - 'A' + 10;
  184. }
  185.  
  186. char *
  187. rl_num(p, cp)
  188.     struct token **p;
  189.     char *cp;
  190. {
  191.     struct token *tp = NEXT_TOKEN;
  192.     int m = 0, base;
  193.     float f, b;
  194.  
  195.     tp = NEXT_TOKEN;
  196.     if (*cp == '0') {
  197.         if (cp[1] == 'x') {
  198.             base = 16;
  199.             cp += 2;
  200.         } else {
  201.             base = 8;
  202.             cp += 1;
  203.         }
  204.     } else
  205.         base = 10;
  206.  
  207.     while (isxdigit(*cp))
  208.         m = base * m + xdtoi(*cp++);
  209.     if (*cp != '.') {
  210.         tp->t_id = TK_INT;
  211.         tp->t_int = m;
  212.     } else {
  213.         ++cp;
  214.         f = m;
  215.         b = 0.1;
  216.         while (isdigit(*cp)) {
  217.             f += (*cp++ - '0') * b;
  218.             b *= 0.1;
  219.         }
  220.         tp->t_id = TK_REAL;
  221.         tp->t_real = f;
  222.     }
  223.     *p = tp;
  224.     return cp;
  225. }
  226.  
  227. char *
  228. rl_misc(p, cp)
  229.     struct token **p;
  230.     char *cp;
  231. {
  232.     struct token *tp = NEXT_TOKEN;
  233.  
  234.     tp->t_id = *cp++ & 0xff;
  235.     *p = tp;
  236.  
  237.     return cp;
  238. }
  239.  
  240. char *
  241. rl_str(p, cp)
  242.     struct token **p;
  243.     char *cp;
  244. {
  245.     char *str = ++cp;
  246.     struct token *tp = NEXT_TOKEN;
  247.  
  248.     while (*cp != '"')
  249.         if (*cp == 0)
  250.             return 0;
  251.         else
  252.             ++cp;
  253.  
  254.     tp->t_id = TK_IDENT;
  255.     tp->t_str = EnterString(str, cp - str);
  256.     *p = tp;
  257.  
  258.     return cp + 1;
  259. }
  260.  
  261. char *
  262. rl_scan(p, cp)
  263.     struct token **p;
  264.     char *cp;
  265. {
  266.     while (*cp && isspace(*cp))
  267.         ++cp;
  268.  
  269.     if (isalpha(*cp)) 
  270.         return rl_id(p, cp);
  271.  
  272.     if (isdigit(*cp) || *cp == '.')
  273.         return rl_num(p, cp);
  274.  
  275.     if (*cp == '\"')
  276.         return rl_str(p, cp);
  277.  
  278.     if (*cp == 0)
  279.         return 0;
  280.  
  281.     return rl_misc(p, cp);
  282. }
  283.  
  284. /*
  285.  * Read a line of input from 'f' and return the corresponding tokens
  286.  * in a null-teminated array.
  287.  */
  288. struct token *
  289. readline(f, prompt)
  290.     FILE *f;
  291.     char *prompt;
  292. {
  293.     struct token **p, *tp;
  294.     char line[MAXLINE];
  295.  
  296.     if (prompt) {
  297.         printf("%s", prompt);
  298.         fflush(stdout);
  299.     }
  300.     RESET_TOKEN;
  301.     if (fgets(line, sizeof line, f) == 0) {
  302.         tp = NEXT_TOKEN;
  303.         tp->t_id = TK_EOF;
  304.         tp->next = 0;
  305.     } else {
  306.         char *cp = line;
  307.         p = &tp;
  308.  
  309.         while (cp = rl_scan(p, cp))
  310.             p = &(*p)->next;
  311.         *p = 0;
  312.     }
  313.     return tp;
  314. }
  315.  
  316. ptokens(tp)
  317.     struct token *tp;
  318. {
  319.     for (; tp != 0; tp = tp->next) {
  320.         switch (tp->t_id) {
  321.         default:
  322.             printf("misc %d '%c'\n", tp->t_id,
  323.                    isprint(tp->t_id) ? tp->t_id : '?');
  324.             break;
  325.         case TK_IDENT:
  326.             printf("ident: \"%s\"\n", tp->t_str);
  327.             break;
  328.         case TK_INT:
  329.             printf("int: %d 0x%x 0%o\n", tp->t_int, 
  330.                   tp->t_int, tp->t_int);
  331.             break;
  332.         case TK_REAL:
  333.             printf("real: %f\n", tp->t_real);
  334.             break;
  335.         case TK_EOF:
  336.             printf("eof\n");
  337.             break;
  338.         }
  339.     }
  340. }
  341.  
  342. /* XXX Try yo look up if a name. */
  343. u_long
  344. tokint(tp)
  345.     struct token *tp;
  346. {
  347.     if (tp->t_id != TK_INT)
  348.         return 0;
  349.     return tp->t_int;
  350. }
  351.     
  352. char *
  353. token_string(tp)
  354.     struct token *tp;
  355. {
  356.     char buf[80], *cp = buf;
  357.  
  358.     for (; tp != 0; tp = tp->next)
  359.         *cp++ = tp->t_id;
  360.  
  361.     return EnterString(buf, cp - buf);
  362. }
  363.