]> git.saurik.com Git - bison.git/blame - src/closure.c
* src/getargs.c (usage): Refresh the help message.
[bison.git] / src / closure.c
CommitLineData
d0fb370f 1/* Subroutines for bison
8dc26b76 2 Copyright (C) 1984, 1989, 2000 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
RS
20
21
8dc26b76 22/* Subroutines of file LR0.c.
d0fb370f
RS
23
24Entry points:
25
26 closure (items, n)
27
8dc26b76
AD
28Given a vector of item numbers items, of length n, set up ruleset and
29itemset to indicate what rules could be run and which items could be
30accepted when those items are the active ones.
d0fb370f 31
8dc26b76
AD
32ruleset contains a bit for each rule. closure sets the bits for all
33rules which could potentially describe the next input to be read.
d0fb370f 34
8dc26b76
AD
35itemset is a vector of item numbers; itemsetend points to just beyond
36the end of the part of it that is significant. closure places there
37the indices of all items which represent units of input that could
38arrive next.
d0fb370f
RS
39
40 initialize_closure (n)
41
8dc26b76
AD
42Allocates the itemset and ruleset vectors, and precomputes useful data
43so that closure can be called. n is the number of elements to
44allocate for itemset.
d0fb370f
RS
45
46 finalize_closure ()
47
48Frees itemset, ruleset and internal data.
49
50*/
51
52#include <stdio.h>
53#include "system.h"
54#include "machine.h"
7612000c 55#include "alloc.h"
d0fb370f
RS
56#include "gram.h"
57
58
59extern short **derives;
60extern char **tags;
61
d2729d44
JT
62void initialize_closure PARAMS((int));
63void set_fderives PARAMS((void));
64void set_firsts PARAMS((void));
65void closure PARAMS((short *, int));
66void finalize_closure PARAMS((void));
d0fb370f 67
d2729d44 68extern void RTC PARAMS((unsigned *, int));
d0fb370f
RS
69
70short *itemset;
71short *itemsetend;
72static unsigned *ruleset;
73
74/* internal data. See comments before set_fderives and set_firsts. */
75static unsigned *fderives;
76static unsigned *firsts;
77
78/* number of words required to hold a bit for each rule */
79static int rulesetsize;
80
81/* number of words required to hold a bit for each variable */
82static int varsetsize;
83
84
85void
d2729d44 86initialize_closure (int n)
d0fb370f
RS
87{
88 itemset = NEW2(n, short);
89
90 rulesetsize = WORDSIZE(nrules + 1);
91 ruleset = NEW2(rulesetsize, unsigned);
92
93 set_fderives();
94}
95
96
97
98/* set fderives to an nvars by nrules matrix of bits
99 indicating which rules can help derive the beginning of the data
100 for each nonterminal. For example, if symbol 5 can be derived as
101 the sequence of symbols 8 3 20, and one of the rules for deriving
102 symbol 8 is rule 4, then the [5 - ntokens, 4] bit in fderives is set. */
103void
d2729d44 104set_fderives (void)
d0fb370f
RS
105{
106 register unsigned *rrow;
107 register unsigned *vrow;
108 register int j;
109 register unsigned cword;
110 register short *rp;
111 register int b;
112
113 int ruleno;
114 int i;
115
116 fderives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
117
118 set_firsts();
119
120 rrow = fderives + ntokens * rulesetsize;
121
122 for (i = ntokens; i < nsyms; i++)
123 {
124 vrow = firsts + ((i - ntokens) * varsetsize);
125 cword = *vrow++;
126 b = 0;
127 for (j = ntokens; j < nsyms; j++)
128 {
129 if (cword & (1 << b))
130 {
131 rp = derives[j];
132 while ((ruleno = *rp++) > 0)
133 {
134 SETBIT(rrow, ruleno);
135 }
136 }
137
138 b++;
139 if (b >= BITS_PER_WORD && j + 1 < nsyms)
140 {
141 cword = *vrow++;
142 b = 0;
143 }
144 }
145
146 rrow += rulesetsize;
147 }
148
149#ifdef DEBUG
150 print_fderives();
151#endif
152
153 FREE(firsts);
154}
155
156
157
8dc26b76
AD
158/* set firsts to be an nvars by nvars bit matrix indicating which
159 items can represent the beginning of the input corresponding to
160 which other items.
161
162 For example, if some rule expands symbol 5 into the sequence of
163 symbols 8 3 20, the symbol 8 can be the beginning of the data for
164 symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is
165 set. */
166
d0fb370f 167void
d2729d44 168set_firsts (void)
d0fb370f
RS
169{
170 register unsigned *row;
171/* register int done; JF unused */
172 register int symbol;
173 register short *sp;
174 register int rowsize;
175
176 int i;
177
178 varsetsize = rowsize = WORDSIZE(nvars);
179
180 firsts = NEW2(nvars * rowsize, unsigned);
181
182 row = firsts;
183 for (i = ntokens; i < nsyms; i++)
184 {
185 sp = derives[i];
186 while (*sp >= 0)
187 {
188 symbol = ritem[rrhs[*sp++]];
189 if (ISVAR(symbol))
190 {
191 symbol -= ntokens;
192 SETBIT(row, symbol);
193 }
194 }
195
196 row += rowsize;
197 }
198
199 RTC(firsts, nvars);
200
201#ifdef DEBUG
8dc26b76 202 print_firsts ();
d0fb370f
RS
203#endif
204}
205
206
207void
d2729d44 208closure (short *core, int n)
d0fb370f
RS
209{
210 register int ruleno;
211 register unsigned word;
212 register short *csp;
213 register unsigned *dsp;
214 register unsigned *rsp;
215
216 short *csend;
217 unsigned *rsend;
218 int symbol;
219 int itemno;
220
221 rsp = ruleset;
222 rsend = ruleset + rulesetsize;
223 csend = core + n;
224
225 if (n == 0)
226 {
227 dsp = fderives + start_symbol * rulesetsize;
228 while (rsp < rsend)
229 *rsp++ = *dsp++;
230 }
231 else
232 {
233 while (rsp < rsend)
234 *rsp++ = 0;
235
236 csp = core;
237 while (csp < csend)
238 {
239 symbol = ritem[*csp++];
240 if (ISVAR(symbol))
241 {
242 dsp = fderives + symbol * rulesetsize;
243 rsp = ruleset;
244 while (rsp < rsend)
245 *rsp++ |= *dsp++;
246 }
247 }
248 }
249
250 ruleno = 0;
251 itemsetend = itemset;
252 csp = core;
253 rsp = ruleset;
254 while (rsp < rsend)
255 {
256 word = *rsp++;
257 if (word == 0)
258 {
259 ruleno += BITS_PER_WORD;
260 }
261 else
262 {
263 register int b;
264
265 for (b = 0; b < BITS_PER_WORD; b++)
266 {
267 if (word & (1 << b))
268 {
269 itemno = rrhs[ruleno];
270 while (csp < csend && *csp < itemno)
271 *itemsetend++ = *csp++;
272 *itemsetend++ = itemno;
273 }
274
275 ruleno++;
276 }
277 }
278 }
279
280 while (csp < csend)
281 *itemsetend++ = *csp++;
282
283#ifdef DEBUG
284 print_closure(n);
285#endif
286}
287
288
289void
d2729d44 290finalize_closure (void)
d0fb370f
RS
291{
292 FREE(itemset);
293 FREE(ruleset);
294 FREE(fderives + ntokens * rulesetsize);
295}
296
297
298
299#ifdef DEBUG
300
301print_closure(n)
302int n;
303{
304 register short *isp;
305
8dc26b76 306 printf ("\n\nn = %d\n\n", n);
d0fb370f 307 for (isp = itemset; isp < itemsetend; isp++)
8dc26b76 308 printf (" %d\n", *isp);
d0fb370f
RS
309}
310
311
d2729d44
JT
312void
313print_firsts (void)
d0fb370f
RS
314{
315 register int i;
316 register int j;
317 register unsigned *rowp;
318
8dc26b76 319 printf ("\n\n\nFIRSTS\n\n");
d0fb370f
RS
320
321 for (i = ntokens; i < nsyms; i++)
322 {
8dc26b76 323 printf ("\n\n%s firsts\n\n", tags[i]);
d0fb370f
RS
324
325 rowp = firsts + ((i - ntokens) * varsetsize);
326
327 for (j = 0; j < nvars; j++)
328 if (BITISSET (rowp, j))
8dc26b76 329 printf (" %s\n", tags[j + ntokens]);
d0fb370f
RS
330 }
331}
332
333
d2729d44
JT
334void
335print_fderives (void)
d0fb370f
RS
336{
337 register int i;
338 register int j;
339 register unsigned *rp;
340
8dc26b76 341 printf ("\n\n\nFDERIVES\n");
d0fb370f
RS
342
343 for (i = ntokens; i < nsyms; i++)
344 {
8dc26b76 345 printf ("\n\n%s derives\n\n", tags[i]);
d0fb370f
RS
346 rp = fderives + i * rulesetsize;
347
348 for (j = 0; j <= nrules; j++)
349 if (BITISSET (rp, j))
8dc26b76 350 printf (" %d\n", j);
d0fb370f
RS
351 }
352
353 fflush(stdout);
354}
355
356#endif