]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.bin/yacc/closure.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.bin / yacc / closure.c
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
39 static char sccsid[] = "@(#)closure.c   5.3 (Berkeley) 5/24/93";
40 #endif
41 #endif
42
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45
46 #include <stdlib.h>
47 #include "defs.h"
48
49 short *itemset;
50 short *itemsetend;
51 unsigned *ruleset;
52
53 static void set_EFF(void);
54 #ifdef DEBUG
55 static void print_closure(int);
56 static void print_EFF();
57 static void print_first_derives();
58 #endif
59
60 static unsigned *first_derives;
61 static unsigned *EFF;
62
63
64 static void
65 set_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
101 void
102 set_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         rrow += rulesetsize;
146     }
147
148 #ifdef  DEBUG
149     print_first_derives();
150 #endif
151
152     FREE(EFF);
153 }
154
155
156 void
157 closure(nucleus, n)
158 short *nucleus;
159 int n;
160 {
161     int ruleno;
162     unsigned word;
163     unsigned i;
164     short *csp;
165     unsigned *dsp;
166     unsigned *rsp;
167     int rulesetsize;
168
169     short *csend;
170     unsigned *rsend;
171     int symbol;
172     int itemno;
173
174     rulesetsize = WORDSIZE(nrules);
175     rsend = ruleset + rulesetsize;
176     for (rsp = ruleset; rsp < rsend; rsp++)
177         *rsp = 0;
178
179     csend = nucleus + n;
180     for (csp = nucleus; csp < csend; ++csp)
181     {
182         symbol = ritem[*csp];
183         if (ISVAR(symbol))
184         {
185             dsp = first_derives + symbol * rulesetsize;
186             rsp = ruleset;
187             while (rsp < rsend)
188                 *rsp++ |= *dsp++;
189         }
190     }
191
192     ruleno = 0;
193     itemsetend = itemset;
194     csp = nucleus;
195     for (rsp = ruleset; rsp < rsend; ++rsp)
196     {
197         word = *rsp;
198         if (word)
199         {
200             for (i = 0; i < BITS_PER_WORD; ++i)
201             {
202                 if (word & (1 << i))
203                 {
204                     itemno = rrhs[ruleno+i];
205                     while (csp < csend && *csp < itemno)
206                         *itemsetend++ = *csp++;
207                     *itemsetend++ = itemno;
208                     while (csp < csend && *csp == itemno)
209                         ++csp;
210                 }
211             }
212         }
213         ruleno += BITS_PER_WORD;
214     }
215
216     while (csp < csend)
217         *itemsetend++ = *csp++;
218
219 #ifdef  DEBUG
220   print_closure(n);
221 #endif
222 }
223
224
225
226 void
227 finalize_closure()
228 {
229   FREE(itemset);
230   FREE(ruleset);
231   FREE(first_derives + ntokens * WORDSIZE(nrules));
232 }
233
234
235 #ifdef  DEBUG
236
237 static void
238 print_closure(n)
239 int n;
240 {
241   short *isp;
242
243   printf("\n\nn = %d\n\n", n);
244   for (isp = itemset; isp < itemsetend; isp++)
245     printf("   %d\n", *isp);
246 }
247
248
249 static void
250 print_EFF()
251 {
252     int i, j;
253     unsigned *rowp;
254     unsigned word;
255     unsigned k;
256
257     printf("\n\nEpsilon Free Firsts\n");
258
259     for (i = start_symbol; i < nsyms; i++)
260     {
261         printf("\n%s", symbol_name[i]);
262         rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
263         word = *rowp++;
264
265         k = BITS_PER_WORD;
266         for (j = 0; j < nvars; k++, j++)
267         {
268             if (k >= BITS_PER_WORD)
269             {
270                 word = *rowp++;
271                 k = 0;
272             }
273
274             if (word & (1 << k))
275                 printf("  %s", symbol_name[start_symbol + j]);
276         }
277     }
278 }
279
280
281 static void
282 print_first_derives()
283 {
284     int i;
285     int j;
286     unsigned *rp;
287     unsigned cword;
288     unsigned k;
289
290     printf("\n\n\nFirst Derives\n");
291
292     for (i = start_symbol; i < nsyms; i++)
293     {
294         printf("\n%s derives\n", symbol_name[i]);
295         rp = first_derives + i * WORDSIZE(nrules);
296         k = BITS_PER_WORD;
297         for (j = 0; j <= nrules; k++, j++)
298         {
299           if (k >= BITS_PER_WORD)
300           {
301               cword = *rp++;
302               k = 0;
303           }
304
305           if (cword & (1 << k))
306             printf("   %d\n", j);
307         }
308     }
309
310   fflush(stdout);
311 }
312
313 #endif