]> git.saurik.com Git - bison.git/blame - src/closure.c
* NEWS (2.3a+): Mention yesterday's state-removal change.
[bison.git] / src / closure.c
CommitLineData
c7bd07f7
PE
1/* Closures for Bison
2
75ad86ee 3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2007 Free
2cec9080 4 Software Foundation, Inc.
d0fb370f 5
8dc26b76 6 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 7
8dc26b76
AD
8 Bison is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
d0fb370f 12
8dc26b76
AD
13 Bison is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
d0fb370f 17
8dc26b76
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to the Free
0fb669f9
PE
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
d0fb370f 22
2cec9080 23#include <config.h>
d0fb370f 24#include "system.h"
c7bd07f7
PE
25
26#include <bitset.h>
27#include <bitsetv-print.h>
28#include <bitsetv.h>
29#include <quotearg.h>
30
31#include "closure.h"
32#include "derives.h"
9bfe901c 33#include "getargs.h"
d0fb370f 34#include "gram.h"
2c5f66ed 35#include "reader.h"
c7bd07f7 36#include "symtab.h"
d0fb370f 37
b2872512 38/* NITEMSET is the size of the array ITEMSET. */
c7bd07f7 39item_number *itemset;
b09f4f48 40size_t nitemset;
fb908786 41
dfdb1797 42static bitset ruleset;
d0fb370f
RS
43
44/* internal data. See comments before set_fderives and set_firsts. */
914feea9
AD
45static bitsetv fderives = NULL;
46static bitsetv firsts = NULL;
d0fb370f 47
03ec521c 48/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
7086e707 49#define FDERIVES(Var) fderives[(Var) - ntokens]
d8a0245c 50#define FIRSTS(Var) firsts[(Var) - ntokens]
2fa6973e 51\f
d0fb370f 52
2fa6973e
AD
53/*-----------------.
54| Debugging code. |
55`-----------------*/
d0fb370f 56
2fa6973e 57static void
c7bd07f7 58print_closure (char const *title, item_number *array, size_t size)
2fa6973e 59{
23cbcc6c 60 size_t i;
427c0dda 61 fprintf (stderr, "Closure: %s\n", title);
23cbcc6c
AD
62 for (i = 0; i < size; ++i)
63 {
c7bd07f7 64 item_number *rp;
23cbcc6c 65 fprintf (stderr, " %2d: .", array[i]);
75142d45 66 for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
97650f4e 67 fprintf (stderr, " %s", symbols[*rp]->tag);
427c0dda 68 fprintf (stderr, " (rule %d)\n", -*rp - 1);
23cbcc6c
AD
69 }
70 fputs ("\n\n", stderr);
2fa6973e
AD
71}
72
73
74static void
75print_firsts (void)
d0fb370f 76{
c7bd07f7 77 symbol_number i, j;
2fa6973e 78
2f4f028d 79 fprintf (stderr, "FIRSTS\n");
2fa6973e
AD
80 for (i = ntokens; i < nsyms; i++)
81 {
613f5e1a 82 bitset_iterator iter;
97650f4e 83 fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
613f5e1a
AD
84 BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
85 {
86 fprintf (stderr, "\t\t%s\n",
87 symbols[j + ntokens]->tag);
88 }
2fa6973e 89 }
2f4f028d 90 fprintf (stderr, "\n\n");
d0fb370f
RS
91}
92
93
2fa6973e
AD
94static void
95print_fderives (void)
96{
9222837b 97 int i;
c7bd07f7 98 rule_number r;
2fa6973e 99
2f4f028d 100 fprintf (stderr, "FDERIVES\n");
2fa6973e
AD
101 for (i = ntokens; i < nsyms; i++)
102 {
613f5e1a 103 bitset_iterator iter;
97650f4e 104 fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
613f5e1a
AD
105 BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
106 {
e1a4f3a4
AD
107 fprintf (stderr, "\t\t%3d ", r);
108 rule_rhs_print (&rules[r], stderr);
613f5e1a 109 }
2fa6973e 110 }
2f4f028d 111 fprintf (stderr, "\n\n");
2fa6973e 112}
2fa6973e 113\f
d8a0245c
AD
114/*------------------------------------------------------------------.
115| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
116| items can represent the beginning of the input corresponding to |
117| which other items. |
118| |
119| For example, if some rule expands symbol 5 into the sequence of |
120| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
121| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
122| (5)) is set. |
123`------------------------------------------------------------------*/
2fa6973e
AD
124
125static void
126set_firsts (void)
127{
c7bd07f7 128 symbol_number i, j;
2fa6973e 129
914feea9
AD
130 firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
131
2fa6973e 132 for (i = ntokens; i < nsyms; i++)
bb7c2bc6 133 for (j = 0; derives[i - ntokens][j]; ++j)
914feea9 134 {
bb7c2bc6 135 item_number sym = derives[i - ntokens][j]->rhs[0];
c7bd07f7
PE
136 if (ISVAR (sym))
137 bitset_set (FIRSTS (i), sym - ntokens);
914feea9 138 }
2fa6973e 139
273a74fa 140 if (trace_flag & trace_sets)
427c0dda 141 bitsetv_matrix_dump (stderr, "RTC: Firsts Input", firsts);
65ccf9fc 142 bitsetv_reflexive_transitive_closure (firsts);
273a74fa 143 if (trace_flag & trace_sets)
427c0dda 144 bitsetv_matrix_dump (stderr, "RTC: Firsts Output", firsts);
2fa6973e 145
273a74fa 146 if (trace_flag & trace_sets)
9bfe901c 147 print_firsts ();
2fa6973e
AD
148}
149
150/*-------------------------------------------------------------------.
151| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
152| rules can help derive the beginning of the data for each |
153| nonterminal. |
154| |
155| For example, if symbol 5 can be derived as the sequence of symbols |
156| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
157| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
158`-------------------------------------------------------------------*/
d0fb370f 159
4a120d45 160static void
d2729d44 161set_fderives (void)
d0fb370f 162{
c7bd07f7
PE
163 symbol_number i, j;
164 rule_number k;
d0fb370f 165
4b3d3a8e 166 fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
d0fb370f 167
2fa6973e 168 set_firsts ();
d0fb370f 169
1cbcf2e7
AD
170 for (i = ntokens; i < nsyms; ++i)
171 for (j = ntokens; j < nsyms; ++j)
d8a0245c 172 if (bitset_test (FIRSTS (i), j - ntokens))
bb7c2bc6
PE
173 for (k = 0; derives[j - ntokens][k]; ++k)
174 bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
d0fb370f 175
273a74fa 176 if (trace_flag & trace_sets)
9bfe901c 177 print_fderives ();
d0fb370f 178
914feea9 179 bitsetv_free (firsts);
d0fb370f 180}
1565b720 181
2fa6973e 182\f
d0fb370f 183
2fa6973e 184void
da2a7671 185new_closure (unsigned int n)
d0fb370f 186{
da2a7671 187 itemset = xnmalloc (n, sizeof *itemset);
d0fb370f 188
4b3d3a8e 189 ruleset = bitset_create (nrules, BITSET_FIXED);
d0fb370f 190
2fa6973e 191 set_fderives ();
d0fb370f
RS
192}
193
194
2fa6973e 195
d0fb370f 196void
f6fbd3da 197closure (item_number *core, size_t n)
d0fb370f 198{
576890b7 199 /* Index over CORE. */
f6fbd3da 200 size_t c;
576890b7 201
d2b04478 202 /* A bit index over RULESET. */
c7bd07f7 203 rule_number ruleno;
d0fb370f 204
613f5e1a
AD
205 bitset_iterator iter;
206
273a74fa 207 if (trace_flag & trace_sets)
427c0dda 208 print_closure ("input", core, n);
c87d4863 209
643a5994 210 bitset_zero (ruleset);
d0fb370f 211
643a5994
AD
212 for (c = 0; c < n; ++c)
213 if (ISVAR (ritem[core[c]]))
214 bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
d0fb370f 215
b09f4f48 216 nitemset = 0;
576890b7 217 c = 0;
613f5e1a
AD
218 BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
219 {
c7bd07f7 220 item_number itemno = rules[ruleno].rhs - ritem;
613f5e1a
AD
221 while (c < n && core[c] < itemno)
222 {
b09f4f48
JD
223 itemset[nitemset] = core[c];
224 nitemset++;
613f5e1a
AD
225 c++;
226 }
b09f4f48
JD
227 itemset[nitemset] = itemno;
228 nitemset++;
613f5e1a 229 };
d0fb370f 230
576890b7
AD
231 while (c < n)
232 {
b09f4f48
JD
233 itemset[nitemset] = core[c];
234 nitemset++;
576890b7
AD
235 c++;
236 }
d0fb370f 237
273a74fa 238 if (trace_flag & trace_sets)
b09f4f48 239 print_closure ("output", itemset, nitemset);
d0fb370f
RS
240}
241
242
243void
2fa6973e 244free_closure (void)
d0fb370f 245{
afbb696d 246 free (itemset);
dfdb1797 247 bitset_free (ruleset);
914feea9 248 bitsetv_free (fderives);
d0fb370f 249}