]> git.saurik.com Git - bison.git/blame - src/closure.c
* src/closure.h: New file.
[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
d0fb370f 22#include "system.h"
7612000c 23#include "alloc.h"
d0fb370f 24#include "gram.h"
2fa6973e 25#include "closure.h"
d0fb370f
RS
26
27extern short **derives;
28extern char **tags;
29
2fa6973e 30extern void RTC PARAMS ((unsigned *, int));
d0fb370f
RS
31
32short *itemset;
33short *itemsetend;
34static unsigned *ruleset;
35
36/* internal data. See comments before set_fderives and set_firsts. */
37static unsigned *fderives;
38static unsigned *firsts;
39
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
AD
45\f
46#if DEBUG
d0fb370f 47
2fa6973e
AD
48/*-----------------.
49| Debugging code. |
50`-----------------*/
d0fb370f 51
2fa6973e
AD
52static void
53print_closure (int n)
54{
55 short *isp;
56
57 printf ("\n\nn = %d\n\n", n);
58 for (isp = itemset; isp < itemsetend; isp++)
59 printf (" %d\n", *isp);
60}
61
62
63static void
64print_firsts (void)
d0fb370f 65{
2fa6973e
AD
66 int i;
67 int j;
68 unsigned *rowp;
69
70 printf ("\n\n\nFIRSTS\n\n");
71
72 for (i = ntokens; i < nsyms; i++)
73 {
74 printf ("\n\n%s firsts\n\n", tags[i]);
d0fb370f 75
2fa6973e 76 rowp = firsts + ((i - ntokens) * varsetsize);
d0fb370f 77
2fa6973e
AD
78 for (j = 0; j < nvars; j++)
79 if (BITISSET (rowp, j))
80 printf (" %s\n", tags[j + ntokens]);
81 }
d0fb370f
RS
82}
83
84
2fa6973e
AD
85static void
86print_fderives (void)
87{
88 int i;
89 int j;
90 unsigned *rp;
91
92 printf ("\n\n\nFDERIVES\n");
93
94 for (i = ntokens; i < nsyms; i++)
95 {
96 printf ("\n\n%s derives\n\n", tags[i]);
97 rp = fderives + i * rulesetsize;
98
99 for (j = 0; j <= nrules; j++)
100 if (BITISSET (rp, j))
101 printf (" %d\n", j);
102 }
103
104 fflush (stdout);
105}
106#endif
107\f
108/*-------------------------------------------------------------------.
109| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
110| items can represent the beginning of the input corresponding to |
111| which other items. |
112| |
113| For example, if some rule expands symbol 5 into the sequence of |
114| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
115| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
116`-------------------------------------------------------------------*/
117
118static void
119set_firsts (void)
120{
121 unsigned *row;
122 int symbol;
123 short *sp;
124 int rowsize;
125
126 int i;
127
128 varsetsize = rowsize = WORDSIZE (nvars);
129
130 firsts = NEW2 (nvars * rowsize, unsigned);
131
132 row = firsts;
133 for (i = ntokens; i < nsyms; i++)
134 {
135 sp = derives[i];
136 while (*sp >= 0)
137 {
138 symbol = ritem[rrhs[*sp++]];
139 if (ISVAR (symbol))
140 {
141 symbol -= ntokens;
142 SETBIT (row, symbol);
143 }
144 }
145
146 row += rowsize;
147 }
148
149 RTC (firsts, nvars);
150
151#ifdef DEBUG
152 print_firsts ();
153#endif
154}
155
156/*-------------------------------------------------------------------.
157| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
158| rules can help derive the beginning of the data for each |
159| nonterminal. |
160| |
161| For example, if symbol 5 can be derived as the sequence of symbols |
162| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
163| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
164`-------------------------------------------------------------------*/
d0fb370f 165
4a120d45 166static void
d2729d44 167set_fderives (void)
d0fb370f 168{
2fa6973e
AD
169 unsigned *rrow;
170 unsigned *vrow;
171 int j;
172 unsigned cword;
173 short *rp;
174 int b;
d0fb370f
RS
175
176 int ruleno;
177 int i;
178
2fa6973e 179 fderives = NEW2 (nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
d0fb370f 180
2fa6973e 181 set_firsts ();
d0fb370f
RS
182
183 rrow = fderives + ntokens * rulesetsize;
184
185 for (i = ntokens; i < nsyms; i++)
186 {
187 vrow = firsts + ((i - ntokens) * varsetsize);
188 cword = *vrow++;
189 b = 0;
190 for (j = ntokens; j < nsyms; j++)
191 {
192 if (cword & (1 << b))
193 {
194 rp = derives[j];
195 while ((ruleno = *rp++) > 0)
196 {
2fa6973e 197 SETBIT (rrow, ruleno);
d0fb370f
RS
198 }
199 }
200
201 b++;
202 if (b >= BITS_PER_WORD && j + 1 < nsyms)
203 {
204 cword = *vrow++;
205 b = 0;
206 }
207 }
208
209 rrow += rulesetsize;
210 }
211
212#ifdef DEBUG
2fa6973e 213 print_fderives ();
d0fb370f
RS
214#endif
215
2fa6973e 216 FREE (firsts);
d0fb370f 217}
2fa6973e 218\f
d0fb370f 219
2fa6973e
AD
220void
221new_closure (int n)
d0fb370f 222{
2fa6973e 223 itemset = NEW2 (n, short);
d0fb370f 224
2fa6973e
AD
225 rulesetsize = WORDSIZE (nrules + 1);
226 ruleset = NEW2 (rulesetsize, unsigned);
d0fb370f 227
2fa6973e 228 set_fderives ();
d0fb370f
RS
229}
230
231
2fa6973e 232
d0fb370f 233void
d2729d44 234closure (short *core, int n)
d0fb370f 235{
2fa6973e
AD
236 int ruleno;
237 unsigned word;
238 short *csp;
239 unsigned *dsp;
240 unsigned *rsp;
d0fb370f
RS
241
242 short *csend;
243 unsigned *rsend;
244 int symbol;
245 int itemno;
246
247 rsp = ruleset;
248 rsend = ruleset + rulesetsize;
249 csend = core + n;
250
251 if (n == 0)
252 {
253 dsp = fderives + start_symbol * rulesetsize;
254 while (rsp < rsend)
255 *rsp++ = *dsp++;
256 }
257 else
258 {
259 while (rsp < rsend)
260 *rsp++ = 0;
261
262 csp = core;
263 while (csp < csend)
264 {
265 symbol = ritem[*csp++];
2fa6973e 266 if (ISVAR (symbol))
d0fb370f
RS
267 {
268 dsp = fderives + symbol * rulesetsize;
269 rsp = ruleset;
270 while (rsp < rsend)
271 *rsp++ |= *dsp++;
272 }
273 }
274 }
275
276 ruleno = 0;
277 itemsetend = itemset;
278 csp = core;
279 rsp = ruleset;
280 while (rsp < rsend)
281 {
282 word = *rsp++;
283 if (word == 0)
284 {
285 ruleno += BITS_PER_WORD;
286 }
287 else
288 {
2fa6973e 289 int b;
d0fb370f
RS
290
291 for (b = 0; b < BITS_PER_WORD; b++)
292 {
293 if (word & (1 << b))
294 {
295 itemno = rrhs[ruleno];
296 while (csp < csend && *csp < itemno)
297 *itemsetend++ = *csp++;
298 *itemsetend++ = itemno;
299 }
300
301 ruleno++;
302 }
303 }
304 }
305
306 while (csp < csend)
307 *itemsetend++ = *csp++;
308
2fa6973e
AD
309#if DEBUG
310 print_closure (n);
d0fb370f
RS
311#endif
312}
313
314
315void
2fa6973e 316free_closure (void)
d0fb370f 317{
2fa6973e
AD
318 FREE (itemset);
319 FREE (ruleset);
320 FREE (fderives + ntokens * rulesetsize);
d0fb370f 321}