/usr.bin/yacc/closure.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 306 lines · 225 code · 50 blank · 31 comment · 31 complexity · d5fccf46206dfab6fb98b39435f47941 MD5 · raw file

  1. /*
  2. * Copyright (c) 1989 The Regents of the University of California.
  3. * All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Robert Paul Corbett.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 4. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. */
  32. #if 0
  33. #ifndef lint
  34. static char sccsid[] = "@(#)closure.c 5.3 (Berkeley) 5/24/93";
  35. #endif
  36. #endif
  37. #include <sys/cdefs.h>
  38. __FBSDID("$FreeBSD$");
  39. #include <stdlib.h>
  40. #include "defs.h"
  41. short *itemset;
  42. short *itemsetend;
  43. unsigned *ruleset;
  44. static void set_EFF(void);
  45. #ifdef DEBUG
  46. static void print_closure(int);
  47. static void print_EFF();
  48. static void print_first_derives();
  49. #endif
  50. static unsigned *first_derives;
  51. static unsigned *EFF;
  52. static void
  53. set_EFF(void)
  54. {
  55. unsigned *row;
  56. int symbol;
  57. short *sp;
  58. int rowsize;
  59. int i;
  60. int rule;
  61. rowsize = WORDSIZE(nvars);
  62. EFF = NEW2(nvars * rowsize, unsigned);
  63. row = EFF;
  64. for (i = start_symbol; i < nsyms; i++)
  65. {
  66. sp = derives[i];
  67. for (rule = *sp; rule > 0; rule = *++sp)
  68. {
  69. symbol = ritem[rrhs[rule]];
  70. if (ISVAR(symbol))
  71. {
  72. symbol -= start_symbol;
  73. SETBIT(row, symbol);
  74. }
  75. }
  76. row += rowsize;
  77. }
  78. reflexive_transitive_closure(EFF, nvars);
  79. #ifdef DEBUG
  80. print_EFF();
  81. #endif
  82. }
  83. void
  84. set_first_derives(void)
  85. {
  86. unsigned *rrow;
  87. unsigned *vrow;
  88. int j;
  89. unsigned k;
  90. unsigned cword = 0;
  91. short *rp;
  92. int rule;
  93. int i;
  94. int rulesetsize;
  95. int varsetsize;
  96. rulesetsize = WORDSIZE(nrules);
  97. varsetsize = WORDSIZE(nvars);
  98. first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
  99. set_EFF();
  100. rrow = first_derives + ntokens * rulesetsize;
  101. for (i = start_symbol; i < nsyms; i++)
  102. {
  103. vrow = EFF + ((i - ntokens) * varsetsize);
  104. k = BITS_PER_WORD;
  105. for (j = start_symbol; j < nsyms; k++, j++)
  106. {
  107. if (k >= BITS_PER_WORD)
  108. {
  109. cword = *vrow++;
  110. k = 0;
  111. }
  112. if (cword & (1 << k))
  113. {
  114. rp = derives[j];
  115. while ((rule = *rp++) >= 0)
  116. {
  117. SETBIT(rrow, rule);
  118. }
  119. }
  120. }
  121. rrow += rulesetsize;
  122. }
  123. #ifdef DEBUG
  124. print_first_derives();
  125. #endif
  126. free(EFF);
  127. }
  128. void
  129. closure(short *nucleus, int n)
  130. {
  131. int ruleno;
  132. unsigned word;
  133. unsigned i;
  134. short *csp;
  135. unsigned *dsp;
  136. unsigned *rsp;
  137. int rulesetsize;
  138. short *csend;
  139. unsigned *rsend;
  140. int symbol;
  141. int itemno;
  142. rulesetsize = WORDSIZE(nrules);
  143. rsend = ruleset + rulesetsize;
  144. for (rsp = ruleset; rsp < rsend; rsp++)
  145. *rsp = 0;
  146. csend = nucleus + n;
  147. for (csp = nucleus; csp < csend; ++csp)
  148. {
  149. symbol = ritem[*csp];
  150. if (ISVAR(symbol))
  151. {
  152. dsp = first_derives + symbol * rulesetsize;
  153. rsp = ruleset;
  154. while (rsp < rsend)
  155. *rsp++ |= *dsp++;
  156. }
  157. }
  158. ruleno = 0;
  159. itemsetend = itemset;
  160. csp = nucleus;
  161. for (rsp = ruleset; rsp < rsend; ++rsp)
  162. {
  163. word = *rsp;
  164. if (word)
  165. {
  166. for (i = 0; i < BITS_PER_WORD; ++i)
  167. {
  168. if (word & (1 << i))
  169. {
  170. itemno = rrhs[ruleno+i];
  171. while (csp < csend && *csp < itemno)
  172. *itemsetend++ = *csp++;
  173. *itemsetend++ = itemno;
  174. while (csp < csend && *csp == itemno)
  175. ++csp;
  176. }
  177. }
  178. }
  179. ruleno += BITS_PER_WORD;
  180. }
  181. while (csp < csend)
  182. *itemsetend++ = *csp++;
  183. #ifdef DEBUG
  184. print_closure(n);
  185. #endif
  186. }
  187. void
  188. finalize_closure(void)
  189. {
  190. free(itemset);
  191. free(ruleset);
  192. free(first_derives + ntokens * WORDSIZE(nrules));
  193. }
  194. #ifdef DEBUG
  195. static void
  196. print_closure(int n)
  197. {
  198. short *isp;
  199. printf("\n\nn = %d\n\n", n);
  200. for (isp = itemset; isp < itemsetend; isp++)
  201. printf(" %d\n", *isp);
  202. }
  203. static void
  204. print_EFF(void)
  205. {
  206. int i, j;
  207. unsigned *rowp;
  208. unsigned word;
  209. unsigned k;
  210. printf("\n\nEpsilon Free Firsts\n");
  211. for (i = start_symbol; i < nsyms; i++)
  212. {
  213. printf("\n%s", symbol_name[i]);
  214. rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
  215. word = *rowp++;
  216. k = BITS_PER_WORD;
  217. for (j = 0; j < nvars; k++, j++)
  218. {
  219. if (k >= BITS_PER_WORD)
  220. {
  221. word = *rowp++;
  222. k = 0;
  223. }
  224. if (word & (1 << k))
  225. printf(" %s", symbol_name[start_symbol + j]);
  226. }
  227. }
  228. }
  229. static void
  230. print_first_derives(void)
  231. {
  232. int i;
  233. int j;
  234. unsigned *rp;
  235. unsigned cword;
  236. unsigned k;
  237. printf("\n\n\nFirst Derives\n");
  238. for (i = start_symbol; i < nsyms; i++)
  239. {
  240. printf("\n%s derives\n", symbol_name[i]);
  241. rp = first_derives + i * WORDSIZE(nrules);
  242. k = BITS_PER_WORD;
  243. for (j = 0; j <= nrules; k++, j++)
  244. {
  245. if (k >= BITS_PER_WORD)
  246. {
  247. cword = *rp++;
  248. k = 0;
  249. }
  250. if (cword & (1 << k))
  251. printf(" %d\n", j);
  252. }
  253. }
  254. fflush(stdout);
  255. }
  256. #endif