From: ceriel Date: Thu, 3 Oct 1985 18:31:47 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~5399 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=e494e09063cfcc9ff8ef8e4e9878cea0e0c0bae6;p=ack.git Initial revision --- diff --git a/util/LLgen/src/sets.c b/util/LLgen/src/sets.c new file mode 100644 index 000000000..c37109975 --- /dev/null +++ b/util/LLgen/src/sets.c @@ -0,0 +1,225 @@ +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + */ + +/* + * L L G E N + * + * An Extended LL(1) Parser Generator + * + * Author : Ceriel J.H. Jacobs + */ + +/* + * sets.c + * Some general setmanipulation routines are defined, + * and also two set allocating routines are defined + */ + +# include "types.h" +# include "extern.h" +# include "sets.h" +# include "assert.h" + +# ifndef NORCSID +static string rcsid9 = "$Header$"; +# endif + +/* In this file the following routines are defined: */ +extern setinit(); +extern p_set setalloc(); +extern int setunion(); +extern int setintersect(); +extern setminus(); +extern int setempty(); +extern int findindex(); +extern int setcount(); + +int tbitset; +int setsize,tsetsize; +p_set *setptr, *maxptr, *topptr; + +static unsigned size,nbytes; + +setinit(ntneeded) { + /* + * Initialises some variables needed for setcomputations + */ + register int bitset; + + nbytes = NBYTES(nterminals); + tbitset = ALIGN(nbytes); + tsetsize = NINTS(tbitset); + bitset = tbitset; + if (ntneeded) { + /* nonterminals must be included in the sets */ + bitset += NBYTES(nnonterms); + } + setsize = NINTS(bitset); + tbitset *= 8; +} + +p_set +setalloc(size) int size; { + /* + * Allocate a set of size "size" ints + */ + register p_set t; + register int i; + p_mem alloc(); + + assert(size == tsetsize || size == setsize); + t = (p_set) alloc((unsigned) (size * sizeof(int))); + i = size; + t += i; + for (; i; i--) { + *--t = 0; + } + return t; +} + +int +setunion(a,b,size) register p_set a,b; int size; { + /* + * a = a union b. + * Return 1 if the set a changed + */ + register i; + register j; + int nsub = 0; + + assert(size == tsetsize || size == setsize); + for (i = size; i; i--) { + *a = (j = *a) | *b++; + if (*a++ != j) { + nsub = 1; + } + } + return nsub; +} + +int +setintersect(a,b,size) register p_set a,b; int size; { + /* + * a = a intersect b. + * return 1 if the resut is empty + */ + register i; + register nempty; + + assert(size == tsetsize || size == setsize); + nempty = 1; + for (i = size; i; i--) { + if (*a++ &= *b++) nempty = 0; + } + return nempty; +} + +setminus(a,b,size) register p_set a,b; int size; { + /* + * a = a setminus b + */ + register i; + + assert(size == tsetsize || size == setsize); + for (i = size; i; i--) { + *a++ &= ~(*b++); + } +} + +int +setempty(p) register p_set p; { + /* + * Return 1 if the set p is empty + */ + register i; + + for (i = tsetsize; i; i--) { + if (*p++) return 0; + } + return 1; +} + +int +findindex(set) p_set *set; { + /* + * The set "set" will serve as a recovery set. + * Search for it in the table. If not present, enter it + */ + register p_set *t; + p_mem alloc(),ralloc(); + register p_set a; + register p_set b; + register i; + register j; + int saved; + + /* + * First search for the set in the table + */ + for (t = setptr; t < maxptr; t++) { + a = *t; + b = *set; + for (i = tsetsize; i; i--) { + if (*a++ != *b++) break; + } + if (i) continue; + /* + * Here, the sets are equal. + */ + return nbytes * (t - setptr); + } + /* + * Now check if the set consists of only one element. + * It would be a waste to use a set for that + */ + if (setcount(*set, &saved) == 1) return -h_entry[saved].h_num; + /* + * If it does, return its number as a negative number. + */ + if (maxptr >= topptr) { + /* + * Need new space for the list, in chunks of 50 pointers + */ + if (setptr == 0) { + setptr = (p_set *) alloc(50 * sizeof(p_set)); + size = 50; + maxptr = setptr; + } else { + setptr = (p_set *) ralloc((p_mem) setptr, + (50+size)*sizeof(p_set)); + maxptr = &setptr[size-1]; + size += 50; + } + topptr = &setptr[size-1]; + } + *maxptr = setalloc(tsetsize); + setunion(*maxptr, *set, tsetsize); + return nbytes * (maxptr++ - setptr); +} + +int +setcount(set, saved) register p_set set; int *saved; { + register int i, j; + + for (j = 0, i = 0; i < nterminals; i++) { + if (IN(set,i)) { + j++; + *saved = i; + } + } + return j; +}