]> git.saurik.com Git - bison.git/blame - src/closure.c
* src/closure.c, src/derives.c, src/nullable.c: Adjust various
[bison.git] / src / closure.c
CommitLineData
d0fb370f 1/* Subroutines for bison
2c5f66ed 2 Copyright 1984, 1989, 2000, 2001 Free Software Foundation, Inc.
d0fb370f 3
8dc26b76 4 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 5
8dc26b76
AD
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
d0fb370f 10
8dc26b76
AD
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
d0fb370f 15
8dc26b76
AD
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
d0fb370f 20
d0fb370f 21#include "system.h"
9bfe901c 22#include "getargs.h"
d0fb370f 23#include "gram.h"
2c5f66ed 24#include "reader.h"
2fa6973e 25#include "closure.h"
340ef489 26#include "derives.h"
d7913476 27#include "warshall.h"
d0fb370f
RS
28
29short *itemset;
30short *itemsetend;
31static unsigned *ruleset;
32
33/* internal data. See comments before set_fderives and set_firsts. */
34static unsigned *fderives;
35static unsigned *firsts;
36
c87d4863
AD
37#define FDERIVES(Symbol) (fderives + (Symbol) * rulesetsize)
38#define FIRSTS(Symbol) (firsts + (Symbol) * varsetsize)
39
d0fb370f
RS
40/* number of words required to hold a bit for each rule */
41static int rulesetsize;
42
43/* number of words required to hold a bit for each variable */
44static int varsetsize;
2fa6973e 45\f
d0fb370f 46
2fa6973e
AD
47/*-----------------.
48| Debugging code. |
49`-----------------*/
d0fb370f 50
2fa6973e
AD
51static void
52print_closure (int n)
53{
54 short *isp;
55
c87d4863 56 fprintf (stderr, "n = %d\n", n);
2fa6973e 57 for (isp = itemset; isp < itemsetend; isp++)
2c5f66ed 58 fprintf (stderr, " %d\n", *isp);
c87d4863 59 fprintf (stderr, "\n\n");
2fa6973e
AD
60}
61
62
63static void
64print_firsts (void)
d0fb370f 65{
2fa6973e
AD
66 int i;
67 int j;
68 unsigned *rowp;
69
c87d4863 70 fprintf (stderr, "FIRSTS\n");
2fa6973e
AD
71
72 for (i = ntokens; i < nsyms; i++)
73 {
c87d4863 74 fprintf (stderr, "\t%s firsts\n", tags[i]);
d0fb370f 75
c87d4863 76 rowp = FIRSTS (i - ntokens);
d0fb370f 77
2fa6973e
AD
78 for (j = 0; j < nvars; j++)
79 if (BITISSET (rowp, j))
c87d4863 80 fprintf (stderr, "\t\t%d (%s)\n", j + ntokens, tags[j + ntokens]);
2fa6973e 81 }
c87d4863 82 fprintf (stderr, "\n\n");
d0fb370f
RS
83}
84
85
2fa6973e
AD
86static void
87print_fderives (void)
88{
89 int i;
90 int j;
91 unsigned *rp;
92
c87d4863 93 fprintf (stderr, "FDERIVES\n");
2fa6973e
AD
94
95 for (i = ntokens; i < nsyms; i++)
96 {
c87d4863
AD
97 fprintf (stderr, "\t%s derives\n", tags[i]);
98 rp = FDERIVES (i);
2fa6973e
AD
99
100 for (j = 0; j <= nrules; j++)
101 if (BITISSET (rp, j))
c87d4863 102 fprintf (stderr, "\t\t%d (%s)\n", j, tags[j]);
2fa6973e 103 }
c87d4863 104 fprintf (stderr, "\n\n");
2fa6973e 105}
2fa6973e
AD
106\f
107/*-------------------------------------------------------------------.
108| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
109| items can represent the beginning of the input corresponding to |
110| which other items. |
111| |
112| For example, if some rule expands symbol 5 into the sequence of |
113| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
114| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
115`-------------------------------------------------------------------*/
116
117static void
118set_firsts (void)
119{
120 unsigned *row;
121 int symbol;
122 short *sp;
123 int rowsize;
124
125 int i;
126
127 varsetsize = rowsize = WORDSIZE (nvars);
128
d7913476 129 firsts = XCALLOC (unsigned, nvars * rowsize);
2fa6973e
AD
130
131 row = firsts;
132 for (i = ntokens; i < nsyms; i++)
133 {
134 sp = derives[i];
135 while (*sp >= 0)
136 {
b2ed6e58 137 symbol = ritem[rule_table[*sp++].rhs];
2fa6973e
AD
138 if (ISVAR (symbol))
139 {
140 symbol -= ntokens;
141 SETBIT (row, symbol);
142 }
143 }
144
145 row += rowsize;
146 }
147
148 RTC (firsts, nvars);
149
9bfe901c
AD
150 if (trace_flag)
151 print_firsts ();
2fa6973e
AD
152}
153
154/*-------------------------------------------------------------------.
155| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
156| rules can help derive the beginning of the data for each |
157| nonterminal. |
158| |
159| For example, if symbol 5 can be derived as the sequence of symbols |
160| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
161| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
162`-------------------------------------------------------------------*/
d0fb370f 163
4a120d45 164static void
d2729d44 165set_fderives (void)
d0fb370f 166{
2fa6973e
AD
167 unsigned *rrow;
168 unsigned *vrow;
169 int j;
170 unsigned cword;
171 short *rp;
172 int b;
d0fb370f
RS
173
174 int ruleno;
175 int i;
176
d7913476 177 fderives = XCALLOC (unsigned, nvars * rulesetsize) - ntokens * rulesetsize;
d0fb370f 178
2fa6973e 179 set_firsts ();
d0fb370f 180
c87d4863 181 rrow = FDERIVES (ntokens);
d0fb370f
RS
182
183 for (i = ntokens; i < nsyms; i++)
184 {
c87d4863 185 vrow = FIRSTS (i - ntokens);
d0fb370f
RS
186 cword = *vrow++;
187 b = 0;
188 for (j = ntokens; j < nsyms; j++)
189 {
190 if (cword & (1 << b))
191 {
192 rp = derives[j];
193 while ((ruleno = *rp++) > 0)
c87d4863 194 SETBIT (rrow, ruleno);
d0fb370f
RS
195 }
196
197 b++;
198 if (b >= BITS_PER_WORD && j + 1 < nsyms)
199 {
200 cword = *vrow++;
201 b = 0;
202 }
203 }
204
205 rrow += rulesetsize;
206 }
207
9bfe901c
AD
208 if (trace_flag)
209 print_fderives ();
d0fb370f 210
d7913476 211 XFREE (firsts);
d0fb370f 212}
2fa6973e 213\f
d0fb370f 214
2fa6973e
AD
215void
216new_closure (int n)
d0fb370f 217{
d7913476 218 itemset = XCALLOC (short, n);
d0fb370f 219
2fa6973e 220 rulesetsize = WORDSIZE (nrules + 1);
d7913476 221 ruleset = XCALLOC (unsigned, rulesetsize);
d0fb370f 222
2fa6973e 223 set_fderives ();
d0fb370f
RS
224}
225
226
2fa6973e 227
d0fb370f 228void
d2729d44 229closure (short *core, int n)
d0fb370f 230{
2fa6973e
AD
231 int ruleno;
232 unsigned word;
233 short *csp;
234 unsigned *dsp;
235 unsigned *rsp;
d0fb370f
RS
236
237 short *csend;
238 unsigned *rsend;
239 int symbol;
240 int itemno;
241
c87d4863
AD
242 if (trace_flag)
243 {
244 int i;
245 fprintf (stderr, "Entering closure (items = {");
246 for (i = 0; i < n; ++i)
247 fprintf (stderr, " %d ", core[i]);
248 fprintf (stderr, "}, nitems = %d)\n", n);
249 }
250
d0fb370f
RS
251 rsp = ruleset;
252 rsend = ruleset + rulesetsize;
253 csend = core + n;
254
255 if (n == 0)
256 {
c87d4863 257 dsp = FDERIVES (start_symbol);
d0fb370f
RS
258 while (rsp < rsend)
259 *rsp++ = *dsp++;
260 }
261 else
262 {
263 while (rsp < rsend)
264 *rsp++ = 0;
265
266 csp = core;
267 while (csp < csend)
268 {
269 symbol = ritem[*csp++];
2fa6973e 270 if (ISVAR (symbol))
d0fb370f 271 {
c87d4863 272 dsp = FDERIVES (symbol);
d0fb370f
RS
273 rsp = ruleset;
274 while (rsp < rsend)
275 *rsp++ |= *dsp++;
276 }
277 }
278 }
279
280 ruleno = 0;
281 itemsetend = itemset;
282 csp = core;
283 rsp = ruleset;
284 while (rsp < rsend)
285 {
286 word = *rsp++;
287 if (word == 0)
288 {
289 ruleno += BITS_PER_WORD;
290 }
291 else
292 {
2fa6973e 293 int b;
d0fb370f
RS
294
295 for (b = 0; b < BITS_PER_WORD; b++)
296 {
297 if (word & (1 << b))
298 {
b2ed6e58 299 itemno = rule_table[ruleno].rhs;
d0fb370f
RS
300 while (csp < csend && *csp < itemno)
301 *itemsetend++ = *csp++;
302 *itemsetend++ = itemno;
303 }
304
305 ruleno++;
306 }
307 }
308 }
309
310 while (csp < csend)
311 *itemsetend++ = *csp++;
312
9bfe901c
AD
313 if (trace_flag)
314 print_closure (n);
d0fb370f
RS
315}
316
317
318void
2fa6973e 319free_closure (void)
d0fb370f 320{
d7913476
AD
321 XFREE (itemset);
322 XFREE (ruleset);
323 XFREE (fderives + ntokens * rulesetsize);
d0fb370f 324}