Initial revision
authorceriel <none@none>
Thu, 3 Oct 1985 18:31:47 +0000 (18:31 +0000)
committerceriel <none@none>
Thu, 3 Oct 1985 18:31:47 +0000 (18:31 +0000)
util/LLgen/src/sets.c [new file with mode: 0644]

diff --git a/util/LLgen/src/sets.c b/util/LLgen/src/sets.c
new file mode 100644 (file)
index 0000000..c371099
--- /dev/null
@@ -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;
+}