+static void
+print_fderives (void)
+{
+ int i;
+ int j;
+ unsigned *rp;
+
+ printf ("\n\n\nFDERIVES\n");
+
+ for (i = ntokens; i < nsyms; i++)
+ {
+ printf ("\n\n%s derives\n\n", tags[i]);
+ rp = fderives + i * rulesetsize;
+
+ for (j = 0; j <= nrules; j++)
+ if (BITISSET (rp, j))
+ printf (" %d\n", j);
+ }
+
+ fflush (stdout);
+}
+#endif
+\f
+/*-------------------------------------------------------------------.
+| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
+| items can represent the beginning of the input corresponding to |
+| which other items. |
+| |
+| For example, if some rule expands symbol 5 into the sequence of |
+| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
+| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
+`-------------------------------------------------------------------*/
+
+static void
+set_firsts (void)
+{
+ unsigned *row;
+ int symbol;
+ short *sp;
+ int rowsize;
+
+ int i;
+
+ varsetsize = rowsize = WORDSIZE (nvars);
+
+ firsts = NEW2 (nvars * rowsize, unsigned);
+
+ row = firsts;
+ for (i = ntokens; i < nsyms; i++)
+ {
+ sp = derives[i];
+ while (*sp >= 0)
+ {
+ symbol = ritem[rrhs[*sp++]];
+ if (ISVAR (symbol))
+ {
+ symbol -= ntokens;
+ SETBIT (row, symbol);
+ }
+ }
+
+ row += rowsize;
+ }
+
+ RTC (firsts, nvars);
+
+#ifdef DEBUG
+ print_firsts ();
+#endif
+}
+
+/*-------------------------------------------------------------------.
+| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
+| rules can help derive the beginning of the data for each |
+| nonterminal. |
+| |
+| For example, if symbol 5 can be derived as the sequence of symbols |
+| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
+| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
+`-------------------------------------------------------------------*/