name.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /* Copyright (c) 1991 by the Vrije Universiteit, Amsterdam, the Netherlands.
  2. * For full copyright and restrictions on use see the file COPYING in the top
  3. * level of the LLgen tree.
  4. */
  5. /*
  6. * L L G E N
  7. *
  8. * An Extended LL(1) Parser Generator
  9. *
  10. * Author : Ceriel J.H. Jacobs
  11. */
  12. /*
  13. * name.c
  14. * Defines the symboltable search routine, a name store routine and an
  15. * initialising routine.
  16. */
  17. # include "types.h"
  18. # include "extern.h"
  19. # include "assert.h"
  20. # include "io.h"
  21. # ifndef NORCSID
  22. static string rcsid7 = "$Id$";
  23. # endif
  24. # define HASHSIZE 128
  25. # define NMSIZ 2048 /* Room for names allocated NMSIZ bytes at a time */
  26. static char *name, *maxname;
  27. static p_entry h_root[HASHSIZE]; /* hash table */
  28. static string e_literal = "Illegal literal";
  29. static p_entry entries, maxentries;
  30. static t_info token_info, nont_info;
  31. /* Defined in this file are: */
  32. extern string store();
  33. extern name_init();
  34. STATIC int hash();
  35. STATIC p_entry newentry();
  36. extern p_gram search();
  37. p_mem alloc();
  38. p_mem new_mem();
  39. name_init() {
  40. token_info.i_esize = sizeof (t_token);
  41. token_info.i_incr = 50;
  42. nont_info.i_esize = sizeof (t_nont);
  43. nont_info.i_incr = 50;
  44. search(TERMINAL,"EOFILE",ENTERING);
  45. }
  46. STATIC p_entry
  47. newentry(str, next) string str; p_entry next; {
  48. register p_entry p;
  49. if ((p = entries) == maxentries) {
  50. p = (p_entry) alloc(50 * sizeof(t_entry));
  51. maxentries = p + 50;
  52. }
  53. entries = p + 1;
  54. p->h_name = str;
  55. p->h_next = next;
  56. p->h_type.g_lineno = linecount;
  57. return p;
  58. }
  59. string
  60. store(s) string s; {
  61. /*
  62. * Store a string s in the name table
  63. */
  64. register string s1, t ,u;
  65. u = name;
  66. t = s;
  67. s1 = u;
  68. do {
  69. if (u >= maxname) {
  70. u = alloc(NMSIZ);
  71. maxname = u + NMSIZ;
  72. t = s;
  73. s1 = u;
  74. }
  75. *u++ = *t;
  76. } while (*t++);
  77. name = u;
  78. return s1;
  79. }
  80. STATIC int
  81. hash(str) string str; {
  82. /*
  83. * Compute the hash for string str
  84. */
  85. register int i;
  86. register string l;
  87. l = str;
  88. i = 0;
  89. while (*l != '\0') i += *l++ & 0377;
  90. i += l - str;
  91. return i % HASHSIZE;
  92. }
  93. p_gram
  94. search(type,str,option) register string str; {
  95. /*
  96. * Search for object str.
  97. * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
  98. * option can be ENTERING or BOTH (also looking).
  99. */
  100. register int val = 0;
  101. register p_entry p;
  102. register int i;
  103. int type1;
  104. i = hash(str);
  105. /*
  106. * Walk hash chain
  107. */
  108. for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) {
  109. if(!strcmp(p->h_name,str)) {
  110. type1 = g_gettype(&(p->h_type));
  111. if (type1 != type) {
  112. if (type1 == LITERAL || type == LITERAL) {
  113. continue;
  114. }
  115. if (type == TERMINAL) {
  116. error(linecount,
  117. "%s: is already a nonterminal",
  118. str);
  119. continue;
  120. }
  121. else if (type == NONTERM) {
  122. error(linecount,
  123. "%s : is already a token",
  124. str);
  125. continue;
  126. }
  127. }
  128. if (option==ENTERING) {
  129. error(linecount,
  130. "%s : is already defined",str);
  131. }
  132. p->h_type.g_lineno = linecount;
  133. return &(p->h_type);
  134. }
  135. }
  136. p = newentry(store(str), h_root[i]);
  137. h_root[i] = p;
  138. if (type == TERMINAL || type == LITERAL) {
  139. register p_token pt;
  140. pt = (p_token) new_mem(&token_info);
  141. tokens = (p_token) token_info.i_ptr;
  142. pt->t_string = p->h_name;
  143. if (type == LITERAL) {
  144. if (str[0] == '\\') {
  145. /*
  146. * Handle escapes in literals
  147. */
  148. if (str[2] == '\0') {
  149. switch(str[1]) {
  150. case 'n' :
  151. val = '\n';
  152. break;
  153. case 'r' :
  154. val = '\r';
  155. break;
  156. case 'b' :
  157. val = '\b';
  158. break;
  159. case 'f' :
  160. val = '\f';
  161. break;
  162. case 't' :
  163. val = '\t';
  164. break;
  165. case '\'':
  166. val = '\'';
  167. break;
  168. case '\\':
  169. val = '\\';
  170. break;
  171. default :
  172. error(linecount,e_literal);
  173. }
  174. } else {
  175. /*
  176. * Here, str[2] != '\0'
  177. */
  178. if (str[1] > '3' || str[1] < '0' ||
  179. str[2] > '7' || str[2] < '0' ||
  180. str[3] > '7' || str[3] < '0' ||
  181. str[4] != '\0') error(linecount,e_literal);
  182. val = 64*str[1] - 73*'0' +
  183. 8*str[2] + str[3];
  184. }
  185. } else {
  186. /*
  187. * No escape in literal
  188. */
  189. if (str[1] == '\0') val = str[0];
  190. else error(linecount,e_literal);
  191. }
  192. pt->t_tokno = val;
  193. g_settype(&(p->h_type), LITERAL);
  194. } else {
  195. /*
  196. * Here, type = TERMINAL
  197. */
  198. pt->t_tokno = assval++;
  199. g_settype(&(p->h_type), TERMINAL);
  200. }
  201. g_setcont(&(p->h_type), ntokens);
  202. ntokens++;
  203. return &(p->h_type);
  204. }
  205. /*
  206. * type == NONTERM || type == UNKNOWN
  207. * UNKNOWN and not yet declared means : NONTERM
  208. */
  209. {
  210. register p_nont q;
  211. q = (p_nont) new_mem(&nont_info);
  212. nonterms = (p_nont) nont_info.i_ptr;
  213. q->n_name = p->h_name;
  214. q->n_rule = 0;
  215. q->n_lineno = linecount;
  216. q->n_string = f_input;
  217. q->n_follow = 0;
  218. q->n_flags = 0;
  219. q->n_contains = 0;
  220. g_settype(&(p->h_type), NONTERM);
  221. g_setcont(&(p->h_type), nnonterms);
  222. g_setnpar(&(p->h_type), 0);
  223. nnonterms++;
  224. return &(p->h_type);
  225. }
  226. }