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