name.c 4.8 KB

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