source: trunk/yacc/closure.c@ 3204

Last change on this file since 3204 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