]> git.saurik.com Git - bison.git/blob - src/closure.c
* src/output.c (output_parser): Compute the `#line' lines when
[bison.git] / src / closure.c
1 /* Subroutines for bison
2 Copyright 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 #include "system.h"
22 #include "xalloc.h"
23 #include "gram.h"
24 #include "closure.h"
25 #include "derives.h"
26 #include "warshall.h"
27
28 short *itemset;
29 short *itemsetend;
30 static unsigned *ruleset;
31
32 /* internal data. See comments before set_fderives and set_firsts. */
33 static unsigned *fderives;
34 static unsigned *firsts;
35
36 /* number of words required to hold a bit for each rule */
37 static int rulesetsize;
38
39 /* number of words required to hold a bit for each variable */
40 static int varsetsize;
41 \f
42 #if DEBUG
43
44 /*-----------------.
45 | Debugging code. |
46 `-----------------*/
47
48 static void
49 print_closure (int n)
50 {
51 short *isp;
52
53 printf ("\n\nn = %d\n\n", n);
54 for (isp = itemset; isp < itemsetend; isp++)
55 printf (" %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 printf ("\n\n\nFIRSTS\n\n");
67
68 for (i = ntokens; i < nsyms; i++)
69 {
70 printf ("\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 printf (" %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 printf ("\n\n\nFDERIVES\n");
89
90 for (i = ntokens; i < nsyms; i++)
91 {
92 printf ("\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 printf (" %d\n", j);
98 }
99
100 fflush (stdout);
101 }
102 #endif
103 \f
104 /*-------------------------------------------------------------------.
105 | Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
106 | items can represent the beginning of the input corresponding to |
107 | which other items. |
108 | |
109 | For example, if some rule expands symbol 5 into the sequence of |
110 | symbols 8 3 20, the symbol 8 can be the beginning of the data for |
111 | symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
112 `-------------------------------------------------------------------*/
113
114 static void
115 set_firsts (void)
116 {
117 unsigned *row;
118 int symbol;
119 short *sp;
120 int rowsize;
121
122 int i;
123
124 varsetsize = rowsize = WORDSIZE (nvars);
125
126 firsts = XCALLOC (unsigned, nvars * rowsize);
127
128 row = firsts;
129 for (i = ntokens; i < nsyms; i++)
130 {
131 sp = derives[i];
132 while (*sp >= 0)
133 {
134 symbol = ritem[rrhs[*sp++]];
135 if (ISVAR (symbol))
136 {
137 symbol -= ntokens;
138 SETBIT (row, symbol);
139 }
140 }
141
142 row += rowsize;
143 }
144
145 RTC (firsts, nvars);
146
147 #ifdef DEBUG
148 print_firsts ();
149 #endif
150 }
151
152 /*-------------------------------------------------------------------.
153 | Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
154 | rules can help derive the beginning of the data for each |
155 | nonterminal. |
156 | |
157 | For example, if symbol 5 can be derived as the sequence of symbols |
158 | 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
159 | the [5 - NTOKENS, 4] bit in FDERIVES is set. |
160 `-------------------------------------------------------------------*/
161
162 static void
163 set_fderives (void)
164 {
165 unsigned *rrow;
166 unsigned *vrow;
167 int j;
168 unsigned cword;
169 short *rp;
170 int b;
171
172 int ruleno;
173 int i;
174
175 fderives = XCALLOC (unsigned, nvars * rulesetsize) - ntokens * rulesetsize;
176
177 set_firsts ();
178
179 rrow = fderives + ntokens * rulesetsize;
180
181 for (i = ntokens; i < nsyms; i++)
182 {
183 vrow = firsts + ((i - ntokens) * varsetsize);
184 cword = *vrow++;
185 b = 0;
186 for (j = ntokens; j < nsyms; j++)
187 {
188 if (cword & (1 << b))
189 {
190 rp = derives[j];
191 while ((ruleno = *rp++) > 0)
192 {
193 SETBIT (rrow, ruleno);
194 }
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 #ifdef DEBUG
209 print_fderives ();
210 #endif
211
212 XFREE (firsts);
213 }
214 \f
215
216 void
217 new_closure (int n)
218 {
219 itemset = XCALLOC (short, n);
220
221 rulesetsize = WORDSIZE (nrules + 1);
222 ruleset = XCALLOC (unsigned, rulesetsize);
223
224 set_fderives ();
225 }
226
227
228
229 void
230 closure (short *core, int n)
231 {
232 int ruleno;
233 unsigned word;
234 short *csp;
235 unsigned *dsp;
236 unsigned *rsp;
237
238 short *csend;
239 unsigned *rsend;
240 int symbol;
241 int itemno;
242
243 rsp = ruleset;
244 rsend = ruleset + rulesetsize;
245 csend = core + n;
246
247 if (n == 0)
248 {
249 dsp = fderives + start_symbol * rulesetsize;
250 while (rsp < rsend)
251 *rsp++ = *dsp++;
252 }
253 else
254 {
255 while (rsp < rsend)
256 *rsp++ = 0;
257
258 csp = core;
259 while (csp < csend)
260 {
261 symbol = ritem[*csp++];
262 if (ISVAR (symbol))
263 {
264 dsp = fderives + symbol * rulesetsize;
265 rsp = ruleset;
266 while (rsp < rsend)
267 *rsp++ |= *dsp++;
268 }
269 }
270 }
271
272 ruleno = 0;
273 itemsetend = itemset;
274 csp = core;
275 rsp = ruleset;
276 while (rsp < rsend)
277 {
278 word = *rsp++;
279 if (word == 0)
280 {
281 ruleno += BITS_PER_WORD;
282 }
283 else
284 {
285 int b;
286
287 for (b = 0; b < BITS_PER_WORD; b++)
288 {
289 if (word & (1 << b))
290 {
291 itemno = rrhs[ruleno];
292 while (csp < csend && *csp < itemno)
293 *itemsetend++ = *csp++;
294 *itemsetend++ = itemno;
295 }
296
297 ruleno++;
298 }
299 }
300 }
301
302 while (csp < csend)
303 *itemsetend++ = *csp++;
304
305 #if DEBUG
306 print_closure (n);
307 #endif
308 }
309
310
311 void
312 free_closure (void)
313 {
314 XFREE (itemset);
315 XFREE (ruleset);
316 XFREE (fderives + ntokens * rulesetsize);
317 }