1 /* Copyright (c) 1991 by the Vrije Universiteit, Amsterdam, the Netherlands.
2 * For full copyright and restrictions on use see the file COPYING in the top
3 * level of the LLgen tree.
9 * An Extended LL(1) Parser Generator
11 * Author : Ceriel J.H. Jacobs
16 * Set manipulation and allocation routines.
25 static string rcsid9 = "$Id: sets.c,v 2.8 1997/02/21 11:27:55 ceriel Exp $";
28 /* In this file the following routines are defined: */
30 extern p_set setalloc();
31 extern p_set get_set();
32 extern int setunion();
33 extern int setintersect();
35 extern int setempty();
36 extern int findindex();
37 extern int setcount();
42 p_set *setptr, *maxptr;
43 static t_info set_info;
48 * Initialises some variables needed for setcomputations
52 nbytes = NBYTES(ntokens);
53 bitset = ALIGN(nbytes);
54 tsetsize = NINTS(bitset);
56 /* nonterminals must be included in the sets */
57 bitset += NBYTES(nnonterms);
59 setsize = NINTS(bitset);
60 set_info.i_esize = sizeof(p_set);
67 * Allocate a set that cannot be freed
70 static p_set sets, maxsets;
72 if ((p = sets) >= maxsets) {
73 q = p = (p_set) alloc((unsigned) (50*setsize*sizeof(*sets)));
74 maxsets = p + 50 * setsize;
77 } while (q < maxsets);
86 * Allocate a set which can later be freed.
89 register int size = setsize;
91 p = (p_set) alloc((unsigned) (size * sizeof(*p))) + size;
99 setunion(a,b) register p_set a,b; {
102 * Return 1 if the set a changed
106 register int nsub = 0;
110 *a = (j = *a) | *b++;
119 setintersect(a,b) register p_set a,b; {
122 * return 1 if the result is empty
130 if (*a++ &= *b++) nempty = 0;
135 setminus(a,b) register p_set a,b; {
148 setempty(p) register p_set p; {
150 * Return 1 if the set p is empty
162 findindex(set) p_set set; {
164 * The set "set" will serve as a recovery set.
165 * Search for it in the table. If not present, enter it.
166 * Here is room for improvement. At the moment, the list of
167 * sets is examined with linear search.
177 * First search for the set in the table
179 for (t = setptr; t < maxptr; t++) {
184 if (*a++ != *b++) break;
188 * Here, the sets are equal.
190 return nbytes * (t - setptr);
193 * Now check if the set consists of only one element.
194 * It would be a waste to use a set for that
196 if (setcount(set, &saved) == 1) return -(saved + 1);
198 * If it does, return its number as a negative number.
200 maxptr = (p_set *) new_mem(&set_info);
201 setptr = (p_set *) set_info.i_ptr;
202 *maxptr = setalloc();
203 setunion(*maxptr, set);
204 return nbytes * (maxptr++ - setptr);
208 setcount(set, saved) register p_set set; int *saved; {
211 for (j = 0, i = 0; i < ntokens; i++) {