/bison/src/closure.c

https://github.com/lexxmark/winflexbison · C · 235 lines · 147 code · 38 blank · 50 comment · 22 complexity · 059c76a815b3593adb4d6e1d954ca4b1 MD5 · raw file

  1. /* Closures for Bison
  2. Copyright (C) 1984, 1989, 2000-2002, 2004-2005, 2007, 2009-2015,
  3. 2018-2020 Free Software Foundation, Inc.
  4. This file is part of Bison, the GNU Compiler Compiler.
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include <config.h>
  16. #include "system.h"
  17. #include <bitset.h>
  18. #include <bitsetv.h>
  19. #include "closure.h"
  20. #include "derives.h"
  21. #include "getargs.h"
  22. #include "gram.h"
  23. #include "reader.h"
  24. #include "symtab.h"
  25. /* NITEMSET is the size of the array ITEMSET. */
  26. item_index *itemset;
  27. size_t nitemset;
  28. /* RULESET contains a bit for each rule. CLOSURE sets the bits for
  29. all rules which could potentially describe the next input to be
  30. read. */
  31. static bitset ruleset;
  32. /* internal data. See comments before set_fderives and set_firsts. */
  33. static bitsetv fderives = NULL;
  34. static bitsetv firsts = NULL;
  35. /* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
  36. #define FDERIVES(Var) fderives[(Var) - ntokens]
  37. #define FIRSTS(Var) firsts[(Var) - ntokens]
  38. /*-----------------.
  39. | Debugging code. |
  40. `-----------------*/
  41. static void
  42. closure_print (char const *title, item_index const *array, size_t size)
  43. {
  44. fprintf (stderr, "Closure: %s\n", title);
  45. for (size_t i = 0; i < size; ++i)
  46. {
  47. fprintf (stderr, " %2d: .", array[i]);
  48. item_number *rp;
  49. for (rp = &ritem[array[i]]; 0 <= *rp; ++rp)
  50. fprintf (stderr, " %s", symbols[*rp]->tag);
  51. fprintf (stderr, " (rule %d)\n", item_number_as_rule_number (*rp));
  52. }
  53. fputs ("\n\n", stderr);
  54. }
  55. static void
  56. print_firsts (void)
  57. {
  58. fprintf (stderr, "FIRSTS\n");
  59. for (symbol_number i = ntokens; i < nsyms; ++i)
  60. {
  61. fprintf (stderr, " %s firsts\n", symbols[i]->tag);
  62. bitset_iterator iter;
  63. symbol_number j;
  64. BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
  65. fprintf (stderr, " %s\n", symbols[j + ntokens]->tag);
  66. }
  67. fprintf (stderr, "\n\n");
  68. }
  69. static void
  70. print_fderives (void)
  71. {
  72. fprintf (stderr, "FDERIVES\n");
  73. for (symbol_number i = ntokens; i < nsyms; ++i)
  74. {
  75. fprintf (stderr, " %s derives\n", symbols[i]->tag);
  76. bitset_iterator iter;
  77. rule_number r;
  78. BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
  79. {
  80. fprintf (stderr, " %3d ", r);
  81. rule_rhs_print (&rules[r], stderr);
  82. fprintf (stderr, "\n");
  83. }
  84. }
  85. fprintf (stderr, "\n\n");
  86. }
  87. /*-------------------------------------------------------------------.
  88. | Set FIRSTS to be an NNTERMS array of NNTERMS bitsets indicating |
  89. | which items can represent the beginning of the input corresponding |
  90. | to which other items. |
  91. | |
  92. | For example, if some rule expands symbol 5 into the sequence of |
  93. | symbols 8 3 20, the symbol 8 can be the beginning of the data for |
  94. | symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
  95. | (5)) is set. |
  96. `-------------------------------------------------------------------*/
  97. static void
  98. set_firsts (void)
  99. {
  100. firsts = bitsetv_create (nnterms, nnterms, BITSET_FIXED);
  101. for (symbol_number i = ntokens; i < nsyms; ++i)
  102. for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
  103. {
  104. item_number sym = derives[i - ntokens][j]->rhs[0];
  105. if (ISVAR (sym))
  106. bitset_set (FIRSTS (i), sym - ntokens);
  107. }
  108. if (trace_flag & trace_sets)
  109. bitsetv_matrix_dump (stderr, "RTC: Firsts Input", firsts);
  110. bitsetv_reflexive_transitive_closure (firsts);
  111. if (trace_flag & trace_sets)
  112. bitsetv_matrix_dump (stderr, "RTC: Firsts Output", firsts);
  113. if (trace_flag & trace_sets)
  114. print_firsts ();
  115. }
  116. /*-------------------------------------------------------------------.
  117. | Set FDERIVES to an NNTERMS by NRULES matrix of bits indicating |
  118. | which rules can help derive the beginning of the data for each |
  119. | nonterminal. |
  120. | |
  121. | For example, if symbol 5 can be derived as the sequence of symbols |
  122. | 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
  123. | the [5 - NTOKENS, 4] bit in FDERIVES is set. |
  124. `-------------------------------------------------------------------*/
  125. static void
  126. set_fderives (void)
  127. {
  128. fderives = bitsetv_create (nnterms, nrules, BITSET_FIXED);
  129. set_firsts ();
  130. for (symbol_number i = ntokens; i < nsyms; ++i)
  131. for (symbol_number j = ntokens; j < nsyms; ++j)
  132. if (bitset_test (FIRSTS (i), j - ntokens))
  133. for (rule_number k = 0; derives[j - ntokens][k]; ++k)
  134. bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
  135. if (trace_flag & trace_sets)
  136. print_fderives ();
  137. bitsetv_free (firsts);
  138. }
  139. void
  140. closure_new (int n)
  141. {
  142. itemset = xnmalloc (n, sizeof *itemset);
  143. ruleset = bitset_create (nrules, BITSET_FIXED);
  144. set_fderives ();
  145. }
  146. void
  147. closure (item_index const *core, size_t n)
  148. {
  149. if (trace_flag & trace_closure)
  150. closure_print ("input", core, n);
  151. bitset_zero (ruleset);
  152. for (size_t c = 0; c < n; ++c)
  153. if (ISVAR (ritem[core[c]]))
  154. bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
  155. /* core is sorted on item index in ritem, which is sorted on rule number.
  156. Compute itemset with the same sort. */
  157. nitemset = 0;
  158. size_t c = 0;
  159. /* A bit index over RULESET. */
  160. rule_number ruleno;
  161. bitset_iterator iter;
  162. BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
  163. {
  164. item_index itemno = rules[ruleno].rhs - ritem;
  165. while (c < n && core[c] < itemno)
  166. {
  167. itemset[nitemset] = core[c];
  168. nitemset++;
  169. c++;
  170. }
  171. itemset[nitemset] = itemno;
  172. nitemset++;
  173. };
  174. while (c < n)
  175. {
  176. itemset[nitemset] = core[c];
  177. nitemset++;
  178. c++;
  179. }
  180. if (trace_flag & trace_closure)
  181. closure_print ("output", itemset, nitemset);
  182. }
  183. void
  184. closure_free (void)
  185. {
  186. free (itemset);
  187. bitset_free (ruleset);
  188. bitsetv_free (fderives);
  189. }