PageRenderTime 29ms CodeModel.GetById 7ms app.highlight 17ms RepoModel.GetById 2ms app.codeStats 0ms

/usr.bin/yacc/closure.c

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