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