source: vendor/FreeBSD-yacc/current/closure.c@ 2464

Last change on this file since 2464 was 2464, checked in by bird, 20 years ago

FreeBSD CVS 2005-07-07

File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Paul Corbett.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if 0
38#ifndef lint
39static char sccsid[] = "@(#)closure.c 5.3 (Berkeley) 5/24/93";
40#endif
41#endif
42
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: src/usr.bin/yacc/closure.c,v 1.12 2002/04/09 11:39:05 ru Exp $");
45
46#include <stdlib.h>
47#include "defs.h"
48
49short *itemset;
50short *itemsetend;
51unsigned *ruleset;
52
53static void set_EFF(void);
54#ifdef DEBUG
55static void print_closure(int);
56static void print_EFF();
57static void print_first_derives();
58#endif
59
60static unsigned *first_derives;
61static unsigned *EFF;
62
63
64static void
65set_EFF()
66{
67 unsigned *row;
68 int symbol;
69 short *sp;
70 int rowsize;
71 int i;
72 int rule;
73
74 rowsize = WORDSIZE(nvars);
75 EFF = NEW2(nvars * rowsize, unsigned);
76
77 row = EFF;
78 for (i = start_symbol; i < nsyms; i++)
79 {
80 sp = derives[i];
81 for (rule = *sp; rule > 0; rule = *++sp)
82 {
83 symbol = ritem[rrhs[rule]];
84 if (ISVAR(symbol))
85 {
86 symbol -= start_symbol;
87 SETBIT(row, symbol);
88 }
89 }
90 row += rowsize;
91 }
92
93 reflexive_transitive_closure(EFF, nvars);
94
95#ifdef DEBUG
96 print_EFF();
97#endif
98}
99
100
101void
102set_first_derives()
103{
104 unsigned *rrow;
105 unsigned *vrow;
106 int j;
107 unsigned k;
108 unsigned cword = 0;
109 short *rp;
110
111 int rule;
112 int i;
113 int rulesetsize;
114 int varsetsize;
115
116 rulesetsize = WORDSIZE(nrules);
117 varsetsize = WORDSIZE(nvars);
118 first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
119
120 set_EFF();
121
122 rrow = first_derives + ntokens * rulesetsize;
123 for (i = start_symbol; i < nsyms; i++)
124 {
125 vrow = EFF + ((i - ntokens) * varsetsize);
126 k = BITS_PER_WORD;
127 for (j = start_symbol; j < nsyms; k++, j++)
128 {
129 if (k >= BITS_PER_WORD)
130 {
131 cword = *vrow++;
132 k = 0;
133 }
134
135 if (cword & (1 << k))
136 {
137 rp = derives[j];
138 while ((rule = *rp++) >= 0)
139 {
140 SETBIT(rrow, rule);
141 }
142 }
143 }
144
145 vrow += varsetsize;
146 rrow += rulesetsize;
147 }
148
149#ifdef DEBUG
150 print_first_derives();
151#endif
152
153 FREE(EFF);
154}
155
156
157void
158closure(nucleus, n)
159short *nucleus;
160int n;
161{
162 int ruleno;
163 unsigned word;
164 unsigned i;
165 short *csp;
166 unsigned *dsp;
167 unsigned *rsp;
168 int rulesetsize;
169
170 short *csend;
171 unsigned *rsend;
172 int symbol;
173 int itemno;
174
175 rulesetsize = WORDSIZE(nrules);
176 rsp = ruleset;
177 rsend = ruleset + rulesetsize;
178 for (rsp = ruleset; rsp < rsend; rsp++)
179 *rsp = 0;
180
181 csend = nucleus + n;
182 for (csp = nucleus; csp < csend; ++csp)
183 {
184 symbol = ritem[*csp];
185 if (ISVAR(symbol))
186 {
187 dsp = first_derives + symbol * rulesetsize;
188 rsp = ruleset;
189 while (rsp < rsend)
190 *rsp++ |= *dsp++;
191 }
192 }
193
194 ruleno = 0;
195 itemsetend = itemset;
196 csp = nucleus;
197 for (rsp = ruleset; rsp < rsend; ++rsp)
198 {
199 word = *rsp;
200 if (word)
201 {
202 for (i = 0; i < BITS_PER_WORD; ++i)
203 {
204 if (word & (1 << i))
205 {
206 itemno = rrhs[ruleno+i];
207 while (csp < csend && *csp < itemno)
208 *itemsetend++ = *csp++;
209 *itemsetend++ = itemno;
210 while (csp < csend && *csp == itemno)
211 ++csp;
212 }
213 }
214 }
215 ruleno += BITS_PER_WORD;
216 }
217
218 while (csp < csend)
219 *itemsetend++ = *csp++;
220
221#ifdef DEBUG
222 print_closure(n);
223#endif
224}
225
226
227
228void
229finalize_closure()
230{
231 FREE(itemset);
232 FREE(ruleset);
233 FREE(first_derives + ntokens * WORDSIZE(nrules));
234}
235
236
237#ifdef DEBUG
238
239static void
240print_closure(n)
241int n;
242{
243 short *isp;
244
245 printf("\n\nn = %d\n\n", n);
246 for (isp = itemset; isp < itemsetend; isp++)
247 printf(" %d\n", *isp);
248}
249
250
251static void
252print_EFF()
253{
254 int i, j;
255 unsigned *rowp;
256 unsigned word;
257 unsigned k;
258
259 printf("\n\nEpsilon Free Firsts\n");
260
261 for (i = start_symbol; i < nsyms; i++)
262 {
263 printf("\n%s", symbol_name[i]);
264 rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
265 word = *rowp++;
266
267 k = BITS_PER_WORD;
268 for (j = 0; j < nvars; k++, j++)
269 {
270 if (k >= BITS_PER_WORD)
271 {
272 word = *rowp++;
273 k = 0;
274 }
275
276 if (word & (1 << k))
277 printf(" %s", symbol_name[start_symbol + j]);
278 }
279 }
280}
281
282
283static void
284print_first_derives()
285{
286 int i;
287 int j;
288 unsigned *rp;
289 unsigned cword;
290 unsigned k;
291
292 printf("\n\n\nFirst Derives\n");
293
294 for (i = start_symbol; i < nsyms; i++)
295 {
296 printf("\n%s derives\n", symbol_name[i]);
297 rp = first_derives + i * WORDSIZE(nrules);
298 k = BITS_PER_WORD;
299 for (j = 0; j <= nrules; k++, j++)
300 {
301 if (k >= BITS_PER_WORD)
302 {
303 cword = *rp++;
304 k = 0;
305 }
306
307 if (cword & (1 << k))
308 printf(" %d\n", j);
309 }
310 }
311
312 fflush(stdout);
313}
314
315#endif
Note: See TracBrowser for help on using the repository browser.