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