]> git.saurik.com Git - bison.git/blame_incremental - src/closure.c
* src/closure.c, src/derives.c, src/nullable.c: Adjust various
[bison.git] / src / closure.c
... / ...
CommitLineData
1/* Subroutines for bison
2 Copyright 1984, 1989, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
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.
10
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.
15
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. */
20
21#include "system.h"
22#include "getargs.h"
23#include "gram.h"
24#include "reader.h"
25#include "closure.h"
26#include "derives.h"
27#include "warshall.h"
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
37#define FDERIVES(Symbol) (fderives + (Symbol) * rulesetsize)
38#define FIRSTS(Symbol) (firsts + (Symbol) * varsetsize)
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;
45\f
46
47/*-----------------.
48| Debugging code. |
49`-----------------*/
50
51static void
52print_closure (int n)
53{
54 short *isp;
55
56 fprintf (stderr, "n = %d\n", n);
57 for (isp = itemset; isp < itemsetend; isp++)
58 fprintf (stderr, " %d\n", *isp);
59 fprintf (stderr, "\n\n");
60}
61
62
63static void
64print_firsts (void)
65{
66 int i;
67 int j;
68 unsigned *rowp;
69
70 fprintf (stderr, "FIRSTS\n");
71
72 for (i = ntokens; i < nsyms; i++)
73 {
74 fprintf (stderr, "\t%s firsts\n", tags[i]);
75
76 rowp = FIRSTS (i - ntokens);
77
78 for (j = 0; j < nvars; j++)
79 if (BITISSET (rowp, j))
80 fprintf (stderr, "\t\t%d (%s)\n", j + ntokens, tags[j + ntokens]);
81 }
82 fprintf (stderr, "\n\n");
83}
84
85
86static void
87print_fderives (void)
88{
89 int i;
90 int j;
91 unsigned *rp;
92
93 fprintf (stderr, "FDERIVES\n");
94
95 for (i = ntokens; i < nsyms; i++)
96 {
97 fprintf (stderr, "\t%s derives\n", tags[i]);
98 rp = FDERIVES (i);
99
100 for (j = 0; j <= nrules; j++)
101 if (BITISSET (rp, j))
102 fprintf (stderr, "\t\t%d (%s)\n", j, tags[j]);
103 }
104 fprintf (stderr, "\n\n");
105}
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
129 firsts = XCALLOC (unsigned, nvars * rowsize);
130
131 row = firsts;
132 for (i = ntokens; i < nsyms; i++)
133 {
134 sp = derives[i];
135 while (*sp >= 0)
136 {
137 symbol = ritem[rule_table[*sp++].rhs];
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
150 if (trace_flag)
151 print_firsts ();
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`-------------------------------------------------------------------*/
163
164static void
165set_fderives (void)
166{
167 unsigned *rrow;
168 unsigned *vrow;
169 int j;
170 unsigned cword;
171 short *rp;
172 int b;
173
174 int ruleno;
175 int i;
176
177 fderives = XCALLOC (unsigned, nvars * rulesetsize) - ntokens * rulesetsize;
178
179 set_firsts ();
180
181 rrow = FDERIVES (ntokens);
182
183 for (i = ntokens; i < nsyms; i++)
184 {
185 vrow = FIRSTS (i - ntokens);
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)
194 SETBIT (rrow, ruleno);
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 if (trace_flag)
209 print_fderives ();
210
211 XFREE (firsts);
212}
213\f
214
215void
216new_closure (int n)
217{
218 itemset = XCALLOC (short, n);
219
220 rulesetsize = WORDSIZE (nrules + 1);
221 ruleset = XCALLOC (unsigned, rulesetsize);
222
223 set_fderives ();
224}
225
226
227
228void
229closure (short *core, int n)
230{
231 int ruleno;
232 unsigned word;
233 short *csp;
234 unsigned *dsp;
235 unsigned *rsp;
236
237 short *csend;
238 unsigned *rsend;
239 int symbol;
240 int itemno;
241
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
251 rsp = ruleset;
252 rsend = ruleset + rulesetsize;
253 csend = core + n;
254
255 if (n == 0)
256 {
257 dsp = FDERIVES (start_symbol);
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++];
270 if (ISVAR (symbol))
271 {
272 dsp = FDERIVES (symbol);
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 {
293 int b;
294
295 for (b = 0; b < BITS_PER_WORD; b++)
296 {
297 if (word & (1 << b))
298 {
299 itemno = rule_table[ruleno].rhs;
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
313 if (trace_flag)
314 print_closure (n);
315}
316
317
318void
319free_closure (void)
320{
321 XFREE (itemset);
322 XFREE (ruleset);
323 XFREE (fderives + ntokens * rulesetsize);
324}