]> git.saurik.com Git - bison.git/blob - src/closure.c
* src/closure.c (closure): Use arrays instead of pointers to clarify.
[bison.git] / src / closure.c
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
29 short *itemset;
30 short *itemsetend;
31 static unsigned *ruleset;
32
33 /* internal data. See comments before set_fderives and set_firsts. */
34 static unsigned *fderives;
35 static 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 */
41 static int rulesetsize;
42
43 /* number of words required to hold a bit for each variable */
44 static int varsetsize;
45 \f
46
47 /*-----------------.
48 | Debugging code. |
49 `-----------------*/
50
51 static void
52 print_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
63 static void
64 print_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
86 static void
87 print_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
117 static void
118 set_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
164 static void
165 set_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
215 void
216 new_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
228 void
229 closure (short *core, int n)
230 {
231 int ruleno;
232 short *csp;
233
234 int itemno;
235 int i;
236
237 if (trace_flag)
238 {
239 fprintf (stderr, "Entering closure (items = {");
240 for (i = 0; i < n; ++i)
241 fprintf (stderr, " %d ", core[i]);
242 fprintf (stderr, "}, nitems = %d)\n", n);
243 }
244
245 if (n == 0)
246 {
247 for (i = 0; i < rulesetsize; ++i)
248 ruleset[i] = FDERIVES (start_symbol)[i];
249 }
250 else
251 {
252 for (i = 0; i < rulesetsize; ++i)
253 ruleset[i] = 0;
254
255 for (i = 0; i < n; ++i)
256 {
257 int symbol = ritem[core[i]];
258 if (ISVAR (symbol))
259 {
260 int j;
261 for (j = 0; j < rulesetsize; ++j)
262 ruleset[j] |= FDERIVES (symbol)[j];
263 }
264 }
265 }
266
267 ruleno = 0;
268 itemsetend = itemset;
269 csp = core;
270 for (i= 0; i < rulesetsize; ++i)
271 {
272 int word = ruleset[i];
273 if (word == 0)
274 {
275 ruleno += BITS_PER_WORD;
276 }
277 else
278 {
279 int b;
280
281 for (b = 0; b < BITS_PER_WORD; b++)
282 {
283 if (word & (1 << b))
284 {
285 itemno = rule_table[ruleno].rhs;
286 while (csp < (core + n ) && *csp < itemno)
287 *itemsetend++ = *csp++;
288 *itemsetend++ = itemno;
289 }
290
291 ruleno++;
292 }
293 }
294 }
295
296 while (csp < (core + n))
297 *itemsetend++ = *csp++;
298
299 if (trace_flag)
300 print_closure (n);
301 }
302
303
304 void
305 free_closure (void)
306 {
307 XFREE (itemset);
308 XFREE (ruleset);
309 XFREE (fderives + ntokens * rulesetsize);
310 }