name.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. #ifdef NON_CORRECTING
  46. illegal_gram = search(TERMINAL,"LLILLEGAL",ENTERING);
  47. #endif
  48. }
  49. STATIC p_entry
  50. newentry(str, next) string str; p_entry next; {
  51. register p_entry p;
  52. if ((p = entries) == maxentries) {
  53. p = (p_entry) alloc(50 * sizeof(t_entry));
  54. maxentries = p + 50;
  55. }
  56. entries = p + 1;
  57. p->h_name = str;
  58. p->h_next = next;
  59. p->h_type.g_lineno = linecount;
  60. #ifdef NON_CORRECTING
  61. p->h_type.g_erroneous = 0;
  62. #endif
  63. return p;
  64. }
  65. string
  66. store(s) string s; {
  67. /*
  68. * Store a string s in the name table
  69. */
  70. register string s1, t ,u;
  71. u = name;
  72. t = s;
  73. s1 = u;
  74. do {
  75. if (u >= maxname) {
  76. u = alloc(NMSIZ);
  77. maxname = u + NMSIZ;
  78. t = s;
  79. s1 = u;
  80. }
  81. *u++ = *t;
  82. } while (*t++);
  83. name = u;
  84. return s1;
  85. }
  86. STATIC int
  87. hash(str) string str; {
  88. /*
  89. * Compute the hash for string str
  90. */
  91. register int i;
  92. register string l;
  93. l = str;
  94. i = 0;
  95. while (*l != '\0') i += *l++ & 0377;
  96. i += l - str;
  97. return i % HASHSIZE;
  98. }
  99. p_gram
  100. search(type,str,option) register string str; {
  101. /*
  102. * Search for object str.
  103. * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
  104. * option can be ENTERING or BOTH (also looking).
  105. */
  106. register int val = 0;
  107. register p_entry p;
  108. register int i;
  109. int type1;
  110. i = hash(str);
  111. /*
  112. * Walk hash chain
  113. */
  114. for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) {
  115. if(!strcmp(p->h_name,str)) {
  116. type1 = g_gettype(&(p->h_type));
  117. if (type1 != type) {
  118. if (type1 == LITERAL || type == LITERAL) {
  119. continue;
  120. }
  121. if (type == TERMINAL) {
  122. error(linecount,
  123. "%s: is already a nonterminal",
  124. str);
  125. continue;
  126. }
  127. else if (type == NONTERM) {
  128. error(linecount,
  129. "%s : is already a token",
  130. str);
  131. continue;
  132. }
  133. }
  134. if (option==ENTERING) {
  135. error(linecount,
  136. "%s : is already defined",str);
  137. }
  138. p->h_type.g_lineno = linecount;
  139. return &(p->h_type);
  140. }
  141. }
  142. p = newentry(store(str), h_root[i]);
  143. h_root[i] = p;
  144. if (type == TERMINAL || type == LITERAL) {
  145. register p_token pt;
  146. pt = (p_token) new_mem(&token_info);
  147. tokens = (p_token) token_info.i_ptr;
  148. pt->t_string = p->h_name;
  149. if (type == LITERAL) {
  150. if (str[0] == '\\') {
  151. /*
  152. * Handle escapes in literals
  153. */
  154. if (str[2] == '\0') {
  155. switch(str[1]) {
  156. case 'n' :
  157. val = '\n';
  158. break;
  159. case 'r' :
  160. val = '\r';
  161. break;
  162. case 'b' :
  163. val = '\b';
  164. break;
  165. case 'f' :
  166. val = '\f';
  167. break;
  168. case 't' :
  169. val = '\t';
  170. break;
  171. case '\'':
  172. val = '\'';
  173. break;
  174. case '\\':
  175. val = '\\';
  176. break;
  177. default :
  178. error(linecount,e_literal);
  179. }
  180. } else {
  181. /*
  182. * Here, str[2] != '\0'
  183. */
  184. if (str[1] > '3' || str[1] < '0' ||
  185. str[2] > '7' || str[2] < '0' ||
  186. str[3] > '7' || str[3] < '0' ||
  187. str[4] != '\0') error(linecount,e_literal);
  188. val = 64*str[1] - 73*'0' +
  189. 8*str[2] + str[3];
  190. }
  191. } else {
  192. /*
  193. * No escape in literal
  194. */
  195. if (str[1] == '\0') val = str[0];
  196. else error(linecount,e_literal);
  197. }
  198. pt->t_tokno = val;
  199. g_settype(&(p->h_type), LITERAL);
  200. } else {
  201. /*
  202. * Here, type = TERMINAL
  203. */
  204. pt->t_tokno = assval++;
  205. g_settype(&(p->h_type), TERMINAL);
  206. }
  207. g_setcont(&(p->h_type), ntokens);
  208. ntokens++;
  209. return &(p->h_type);
  210. }
  211. /*
  212. * type == NONTERM || type == UNKNOWN
  213. * UNKNOWN and not yet declared means : NONTERM
  214. */
  215. {
  216. register p_nont q;
  217. q = (p_nont) new_mem(&nont_info);
  218. nonterms = (p_nont) nont_info.i_ptr;
  219. q->n_name = p->h_name;
  220. q->n_rule = 0;
  221. q->n_lineno = linecount;
  222. q->n_string = f_input;
  223. q->n_follow = 0;
  224. q->n_flags = 0;
  225. q->n_contains = 0;
  226. g_settype(&(p->h_type), NONTERM);
  227. g_setcont(&(p->h_type), nnonterms);
  228. g_setnpar(&(p->h_type), 0);
  229. nnonterms++;
  230. return &(p->h_type);
  231. }
  232. }