]> git.saurik.com Git - bison.git/blob - src/closure.c
31073257970bd2b0575fd252b322f90e0bb97054
[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 extern char **tags;
29
30 extern void RTC PARAMS ((unsigned *, int));
31
32 short *itemset;
33 short *itemsetend;
34 static unsigned *ruleset;
35
36 /* internal data. See comments before set_fderives and set_firsts. */
37 static unsigned *fderives;
38 static unsigned *firsts;
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 #if DEBUG
47
48 /*-----------------.
49 | Debugging code. |
50 `-----------------*/
51
52 static void
53 print_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
63 static void
64 print_firsts (void)
65 {
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]);
75
76 rowp = firsts + ((i - ntokens) * varsetsize);
77
78 for (j = 0; j < nvars; j++)
79 if (BITISSET (rowp, j))
80 printf (" %s\n", tags[j + ntokens]);
81 }
82 }
83
84
85 static void
86 print_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
118 static void
119 set_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 `-------------------------------------------------------------------*/
165
166 static void
167 set_fderives (void)
168 {
169 unsigned *rrow;
170 unsigned *vrow;
171 int j;
172 unsigned cword;
173 short *rp;
174 int b;
175
176 int ruleno;
177 int i;
178
179 fderives = NEW2 (nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
180
181 set_firsts ();
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 {
197 SETBIT (rrow, ruleno);
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
213 print_fderives ();
214 #endif
215
216 FREE (firsts);
217 }
218 \f
219
220 void
221 new_closure (int n)
222 {
223 itemset = NEW2 (n, short);
224
225 rulesetsize = WORDSIZE (nrules + 1);
226 ruleset = NEW2 (rulesetsize, unsigned);
227
228 set_fderives ();
229 }
230
231
232
233 void
234 closure (short *core, int n)
235 {
236 int ruleno;
237 unsigned word;
238 short *csp;
239 unsigned *dsp;
240 unsigned *rsp;
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++];
266 if (ISVAR (symbol))
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 {
289 int b;
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
309 #if DEBUG
310 print_closure (n);
311 #endif
312 }
313
314
315 void
316 free_closure (void)
317 {
318 FREE (itemset);
319 FREE (ruleset);
320 FREE (fderives + ntokens * rulesetsize);
321 }