Beispiel #1
0
/**
 * \post:
 *   - \c result = a new \c bitset of size \c ::nritems such that any bit \c i
 *     is set iff <tt>ritem[i]</tt> is a nonterminal after which all ritems in
 *     the same RHS are nullable nonterminals.  In other words, the follows of
 *     a goto on <tt>ritem[i]</tt> include the lookahead set of the item.
 */
static bitset
ielr_compute_ritem_sees_lookahead_set (void)
{
  bitset result = bitset_create (nritems, BITSET_FIXED);
  unsigned int i = nritems-1;
  while (i>0)
    {
      --i;
      while (!item_number_is_rule_number (ritem[i])
             && ISVAR (ritem[i])
             && nullable [item_number_as_symbol_number (ritem[i]) - ntokens])
        bitset_set (result, i--);
      if (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i]))
        bitset_set (result, i--);
      while (!item_number_is_rule_number (ritem[i]) && i>0)
        --i;
    }
  if (trace_flag & trace_ielr)
    {
      fprintf (stderr, "ritem_sees_lookahead_set:\n");
      debug_bitset (result);
      fprintf (stderr, "\n");
    }
  return result;
}
Beispiel #2
0
void set_EFF(void)
{
    unsigned *row;
    int symbol;
    short *sp;
    int rowsize;
    int i;
    int rule;

    rowsize = WORDSIZE(nvars);
    EFF = NEW2(nvars * rowsize, unsigned);

    row = EFF;
    for (i = start_symbol; i < nsyms; i++)
    {
	sp = derives[i];
	for (rule = *sp; rule > 0; rule = *++sp)
	{
	    symbol = ritem[rrhs[rule]];
	    if (ISVAR(symbol))
	    {
		symbol -= start_symbol;
		SETBIT(row, symbol);
	    }
	}
	row += rowsize;
    }

    reflexive_transitive_closure(EFF, nvars);

#ifdef	DEBUG
    print_EFF();
#endif
}
Beispiel #3
0
static void set_EFF(void)
{
    register unsigned *row;
    register Yshort symbol;
    register Yshort *sp;
    register int rowsize;
    register int i;
    register int rule;

    rowsize = WORDSIZE(nvars);
    EFF = NEW2(nvars * rowsize, EFF[0]);

    row = EFF;

    for (i = start_symbol; i < nsyms; ++i)
    {
        sp = derives[i];
        for (rule = *sp; rule > 0; rule = *++sp)
        {
            symbol = ritem[rrhs[rule]];
            if (ISVAR(symbol))
            {
                symbol -= start_symbol;
                SETBIT(row, symbol);
            }
        }
        row += rowsize;
    }

    reflexive_transitive_closure(EFF, nvars);

    if (tflag > 1)
        print_EFF();
}
Beispiel #4
0
initialize_LA()
{
  register int i;
  register int j;
  register int count;
  register reductions *rp;
  register shifts *sp;
  register short *np;

  consistent = NEW2(nstates, char);
  lookaheads = NEW2(nstates + 1, short);

  count = 0;
  for (i = 0; i < nstates; i++)
    {
      register int j;

      lookaheads[i] = count;

      rp = reduction_table[i];
      sp = shift_table[i];
      if (rp && (rp->nreds > 1
          || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]]))))
	count += rp->nreds;
      else
	consistent[i] = 1;

      if (sp)
	for (j = 0; j < sp->nshifts; j++)
	  {
	    if (accessing_symbol[sp->shifts[j]] == error_token_number)
	      {
		consistent[i] = 0;
		break;
	      }
	  }
    }

  lookaheads[nstates] = count;

  LA = NEW2(count * tokensetsize, unsigned);
  LAruleno = NEW2(count, short);
  lookback = NEW2(count, shorts *);

  np = LAruleno;
  for (i = 0; i < nstates; i++)
    {
      if (!consistent[i])
	{
	  if (rp = reduction_table[i])
	    for (j = 0; j < rp->nreds; j++)
	      *np++ = rp->rules[j];
	}
    }
}
Beispiel #5
0
static void
nonterminals_reduce (void)
{
  /* Map the nonterminals to their new index: useful first, useless
     afterwards.  Kept for later report.  */

  symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
  symbol_number n = ntokens;
  symbol_number i;
  for (i = ntokens; i < nsyms; i++)
    if (bitset_test (V, i))
      nontermmap[i - ntokens] = n++;
  for (i = ntokens; i < nsyms; i++)
    if (!bitset_test (V, i))
      {
        nontermmap[i - ntokens] = n++;
        if (symbols[i]->status != used)
          complain (&symbols[i]->location, Wother,
                    _("nonterminal useless in grammar: %s"),
                    symbols[i]->tag);
      }


  /* Shuffle elements of tables indexed by symbol number.  */
  {
    symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);

    for (i = ntokens; i < nsyms; i++)
      symbols[i]->number = nontermmap[i - ntokens];
    for (i = ntokens; i < nsyms; i++)
      symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
    for (i = ntokens; i < nsyms; i++)
      symbols[i] = symbols_sorted[i - ntokens];
    free (symbols_sorted);
  }

  {
    rule_number r;
    for (r = 0; r < nrules; ++r)
      {
        item_number *rhsp;
        for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
          if (ISVAR (*rhsp))
            *rhsp =  symbol_number_as_item_number (nontermmap[*rhsp
                                                              - ntokens]);
      }
    accept->number = nontermmap[accept->number - ntokens];
  }

  nsyms -= nuseless_nonterminals;
  nvars -= nuseless_nonterminals;

  free (nontermmap);
}
Beispiel #6
0
static bool
useful_production (rule_number r, bitset N0)
{
  item_number *rhsp;

  /* A production is useful if all of the nonterminals in its appear
     in the set of useful nonterminals.  */

  for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
    if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
      return false;
  return true;
}
Beispiel #7
0
void
initialize_LA (void)
{
  register int i;
  register int j;
  register int count;
  register reductions *rp;
  register shifts *sp;
  register short *np;

  consistent = NEW2(nstates, char);
  lookaheads = NEW2(nstates + 1, short);

  count = 0;
  for (i = 0; i < nstates; i++)
    {
      register int k;

      lookaheads[i] = count;

      rp = reduction_table[i];
      sp = shift_table[i];
      if (rp && (rp->nreds > 1
          || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]]))))
	count += rp->nreds;
      else
	consistent[i] = 1;

      if (sp)
	for (k = 0; k < sp->nshifts; k++)
	  {
	    if (accessing_symbol[sp->shifts[k]] == error_token_number)
	      {
		consistent[i] = 0;
		break;
	      }
	  }
    }

  lookaheads[nstates] = count;

  if (count == 0)
    {
      LA = NEW2(1 * tokensetsize, unsigned);
      LAruleno = NEW2(1, short);
      lookback = NEW2(1, shorts *);
    }
Beispiel #8
0
static void print_gotos (int stateno)
{
    int i, k;
    int as;
    Value_t * to_state2;
    shifts * sp;

    putc ('\n', verbose_file);
    sp        = shift_table[stateno];
    to_state2 = sp->shift;
    for (i = 0; i < sp->nshifts; ++i)
    {
        k  = to_state2[i];
        as = accessing_symbol[k];
        if (ISVAR (as))
            fprintf (verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
    }
}
Beispiel #9
0
void print_gotos(int stateno)
{
    register int i, k;
    register int as;
    register Yshort *to_state;
    register shifts *sp;

    BtYacc_putc('\n', verbose_file);
    sp = shift_table[stateno];
    to_state = sp->shift;
    for (i = 0; i < sp->nshifts; ++i)
    {
        k = to_state[i];
        as = accessing_symbol[k];
        if (ISVAR(as))
            BtYacc_printf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
    }
}
Beispiel #10
0
void print_actions(int stateno)
{
    register action *p;
    register shifts *sp;
    register int as;

    if (stateno == final_state)
        BtYacc_puts("\t$end  accept\n", verbose_file);

    p = parser[stateno];
    if (p)
    {
        print_shifts(p);
        print_reductions(p, defred[stateno]);
    }

    sp = shift_table[stateno];
    if (sp && sp->nshifts > 0)
    {
        as = accessing_symbol[sp->shift[sp->nshifts - 1]];
        if (ISVAR(as))
            print_gotos(stateno);
    }

    if (tflag > 1)
    {
        BtYacc_puts("\n\n------------ action dump ---------------\n", verbose_file);
        for (p = parser[stateno]; p; p = p->next)
        {
            BtYacc_printf(verbose_file, "\t%-30s  %6s %5d ~ prec %3d, assoc: %3d (%%%-10s), suppress: %d\n",
                        symbol_name[p->symbol],
                        (p->action_code == SHIFT ? "shift" : "reduce"),
                        (p->action_code == SHIFT ? p->number : p->number - 2),
                        p->prec,
                        p->assoc, get_symbol_assoc_str(p->assoc),
                        p->suppressed);
        }
        BtYacc_puts("----------------------------------------\n\n", verbose_file);
    }
}
Beispiel #11
0
void
print_actions(int stateno)
{
	action *p;
	shifts *sp;
	int as;

	if (stateno == final_state)
		fprintf(verbose_file, "\t$end  accept\n");

	p = parser[stateno];
	if (p) {
		print_shifts(p);
		print_reductions(p, defred[stateno]);
	}
	sp = shift_table[stateno];
	if (sp && sp->nshifts > 0) {
		as = accessing_symbol[sp->shift[sp->nshifts - 1]];
		if (ISVAR(as))
			print_gotos(stateno);
	}
}
Beispiel #12
0
void closure(short *nucleus,int n)
{
    int ruleno;
    unsigned word;
    unsigned mask;
    short *csp;
    unsigned *dsp;
    unsigned *rsp;
    int rulesetsize;

    short *csend;
    unsigned *rsend;
    int symbol;
    int itemno;

    rulesetsize = WORDSIZE(nrules);
    rsp = ruleset;
    rsend = ruleset + rulesetsize;
    for (rsp = ruleset; rsp < rsend; rsp++)
      *rsp = 0;

    csend = nucleus + n;
    for (csp = nucleus; csp < csend; ++csp)
    {
	symbol = ritem[*csp];
	if (ISVAR(symbol))
	{
	    dsp = first_derives + symbol * rulesetsize;
	    rsp = ruleset;
	    while (rsp < rsend)
	      *rsp++ |= *dsp++;
	}
    }

    ruleno = 0;
    itemsetend = itemset;
    csp = nucleus;
    for (rsp = ruleset; rsp < rsend; ++rsp)
    {
	word = *rsp;
	if (word == 0) ruleno += BITS_PER_WORD;
	else
	{
	    mask = 1;
	    while (mask)
	    {
		if (word & mask)
		{
		    itemno = rrhs[ruleno];
		    while (csp < csend && *csp < itemno)
		      *itemsetend++ = *csp++;
		    *itemsetend++ = itemno;
		    while (csp < csend && *csp == itemno)
		      ++csp;
		}

		mask <<= 1;
		++ruleno;
	    }
	}
    }

    while (csp < csend)
      *itemsetend++ = *csp++;

#ifdef	DEBUG
    print_closure(n);
#endif
}
Beispiel #13
0
void
set_conflicts (int state)
{
  register int i;
  register int k;
  register shifts *shiftp;
  register unsigned *fp2;
  register unsigned *fp3;
  register unsigned *fp4;
  register unsigned *fp1;
  register int symbol;

  if (consistent[state]) return;

  for (i = 0; i < tokensetsize; i++)
    lookaheadset[i] = 0;

  shiftp = shift_table[state];
  if (shiftp)
    {
      k = shiftp->nshifts;
      for (i = 0; i < k; i++)
	{
	  symbol = accessing_symbol[shiftp->shifts[i]];
	  if (ISVAR(symbol)) break;
	  SETBIT(lookaheadset, symbol);
	}
    }

  k = lookaheads[state + 1];
  fp4 = lookaheadset + tokensetsize;

  /* loop over all rules which require lookahead in this state */
  /* first check for shift-reduce conflict, and try to resolve using precedence  */

  for (i = lookaheads[state]; i < k; i++)
    if (rprec[LAruleno[i]])
      {
	fp1 = LA + i * tokensetsize;
	fp2 = fp1;
	fp3 = lookaheadset;
  
	while (fp3 < fp4)
	  {
	    if (*fp2++ & *fp3++)
	      {
		resolve_sr_conflict(state, i);
		break;
	      }
	  }
      }

  /* loop over all rules which require lookahead in this state */
  /* Check for conflicts not resolved above.  */

  for (i = lookaheads[state]; i < k; i++)
    {
      fp1 = LA + i * tokensetsize;
      fp2 = fp1;
      fp3 = lookaheadset;

      while (fp3 < fp4)
	{
	  if (*fp2++ & *fp3++)
	    {
	      conflicts[state] = 1;
	      any_conflicts = 1;
	    }
	}

      fp2 = fp1;
      fp3 = lookaheadset;

      while (fp3 < fp4)
	*fp3++ |= *fp2++;
    }
}
Beispiel #14
0
void
print_reductions (int state)
{
  register int i;
  register int j;
  register int k;
  register unsigned *fp1;
  register unsigned *fp2;
  register unsigned *fp3;
  register unsigned *fp4;
  register int rule;
  register int symbol;
  register unsigned mask;
  register int m;
  register int n;
  register int default_LA;
  register int default_rule = 0;
  register int cmax;
  register int count;
  register shifts *shiftp;
  register errs *errp;
  int nodefault = 0;

  for (i = 0; i < tokensetsize; i++)
    shiftset[i] = 0;

  shiftp = shift_table[state];
  if (shiftp)
    {
      k = shiftp->nshifts;
      for (i = 0; i < k; i++)
	{
	  if (! shiftp->shifts[i]) continue;
	  symbol = accessing_symbol[shiftp->shifts[i]];
	  if (ISVAR(symbol)) break;
	  /* if this state has a shift for the error token,
	     don't use a default rule.  */
	  if (symbol == error_token_number) nodefault = 1;
	  SETBIT(shiftset, symbol);
	}
    }

  errp = err_table[state];
  if (errp)
    {
      k = errp->nerrs;
      for (i = 0; i < k; i++)
	{
	  if (! errp->errs[i]) continue;
	  symbol = errp->errs[i];
	  SETBIT(shiftset, symbol);
	}
    }

  m = lookaheads[state];
  n = lookaheads[state + 1];

  if (n - m == 1 && ! nodefault)
    {
      default_rule = LAruleno[m];

      fp1 = LA + m * tokensetsize;
      fp2 = shiftset;
      fp3 = lookaheadset;
      fp4 = lookaheadset + tokensetsize;

      while (fp3 < fp4)
	*fp3++ = *fp1++ & *fp2++;

      mask = 1;
      fp3 = lookaheadset;

      for (i = 0; i < ntokens; i++)
	{
	  if (mask & *fp3)
	    fprintf(foutput, _("    %-4s\t[reduce using rule %d (%s)]\n"),
		    tags[i], default_rule, tags[rlhs[default_rule]]);

	  mask <<= 1;
	  if (mask == 0)
	    {
	      mask = 1;
	      fp3++;
	    }
	}

      fprintf(foutput, _("    $default\treduce using rule %d (%s)\n\n"),
	      default_rule, tags[rlhs[default_rule]]);
    }
  else if (n - m >= 1)
    {
      cmax = 0;
      default_LA = -1;
      fp4 = lookaheadset + tokensetsize;

      if (! nodefault)
	for (i = m; i < n; i++)
	  {
	    fp1 = LA + i * tokensetsize;
	    fp2 = shiftset;
	    fp3 = lookaheadset;
  
	    while (fp3 < fp4)
	      *fp3++ = *fp1++ & (~(*fp2++));
  
	    count = 0;
	    mask = 1;
	    fp3 = lookaheadset;
	    for (j = 0; j < ntokens; j++)
	      {
		if (mask & *fp3)
		  count++;
  
		mask <<= 1;
		if (mask == 0)
		  {
		    mask = 1;
		    fp3++;
		  }
	      }
  
	    if (count > cmax)
	      {
		cmax = count;
		default_LA = i;
		default_rule = LAruleno[i];
	      }
  
	    fp2 = shiftset;
	    fp3 = lookaheadset;
  
	    while (fp3 < fp4)
	      *fp2++ |= *fp3++;
	  }

      for (i = 0; i < tokensetsize; i++)
        shiftset[i] = 0;

      if (shiftp)
        {
          k = shiftp->nshifts;
          for (i = 0; i < k; i++)
	    {
	      if (! shiftp->shifts[i]) continue;
	      symbol = accessing_symbol[shiftp->shifts[i]];
	      if (ISVAR(symbol)) break;
	      SETBIT(shiftset, symbol);
	    }
        }

      mask = 1;
      fp1 = LA + m * tokensetsize;
      fp2 = shiftset;
      for (i = 0; i < ntokens; i++)
	{
	  int defaulted = 0;

	  if (mask & *fp2)
	    count = 1;
	  else
	    count = 0;

	  fp3 = fp1;
	  for (j = m; j < n; j++)
	    {
	      if (mask & *fp3)
		{
		  if (count == 0)
		    {
		      if (j != default_LA)
			{
			  rule = LAruleno[j];
			  fprintf(foutput, _("    %-4s\treduce using rule %d (%s)\n"),
				  tags[i], rule, tags[rlhs[rule]]);
			}
		      else defaulted = 1;

		      count++;
		    }
		  else
		    {
		      if (defaulted)
			{
			  rule = LAruleno[default_LA];
			  fprintf(foutput, _("    %-4s\treduce using rule %d (%s)\n"),
				  tags[i], rule, tags[rlhs[rule]]);
			  defaulted = 0;
			}
		      rule = LAruleno[j];
		      fprintf(foutput, _("    %-4s\t[reduce using rule %d (%s)]\n"),
			      tags[i], rule, tags[rlhs[rule]]);
		    }
		}

	      fp3 += tokensetsize;
	    }

	  mask <<= 1;
	  if (mask == 0)
	    {
	      mask = 1;
	      /* We tried incrementing just fp1, and just fp2; both seem wrong.
		 It seems necessary to increment both in sync.  */
	      fp1++;
	      fp2++;
	    }
	}

      if (default_LA >= 0)
	{
	  fprintf(foutput, _("    $default\treduce using rule %d (%s)\n"),
		  default_rule, tags[rlhs[default_rule]]);
	}

      putc('\n', foutput);
    }
}
Beispiel #15
0
void
closure(Value_t *nucleus, int n)
{
    unsigned ruleno;
    unsigned word;
    unsigned i;
    Value_t *csp;
    unsigned *dsp;
    unsigned *rsp;
    int rulesetsize;

    Value_t *csend;
    unsigned *rsend;
    int symbol;
    Value_t itemno;

    rulesetsize = WORDSIZE(nrules);
    rsend = ruleset + rulesetsize;
    for (rsp = ruleset; rsp < rsend; rsp++)
	*rsp = 0;

    csend = nucleus + n;
    for (csp = nucleus; csp < csend; ++csp)
    {
	symbol = ritem[*csp];
	if (ISVAR(symbol))
	{
	    dsp = first_derives + symbol * rulesetsize;
	    rsp = ruleset;
	    while (rsp < rsend)
		*rsp++ |= *dsp++;
	}
    }

    ruleno = 0;
    itemsetend = itemset;
    csp = nucleus;
    for (rsp = ruleset; rsp < rsend; ++rsp)
    {
	word = *rsp;
	if (word)
	{
	    for (i = 0; i < BITS_PER_WORD; ++i)
	    {
		if (word & (unsigned)(1 << i))
		{
		    itemno = rrhs[ruleno + i];
		    while (csp < csend && *csp < itemno)
			*itemsetend++ = *csp++;
		    *itemsetend++ = itemno;
		    while (csp < csend && *csp == itemno)
			++csp;
		}
	    }
	}
	ruleno += BITS_PER_WORD;
    }

    while (csp < csend)
	*itemsetend++ = *csp++;

#ifdef	DEBUG
    print_closure(n);
#endif
}
Beispiel #16
0
static void
initialize_F(void)
{
    int i;
    int j;
    int k;
    shifts *sp;
    Value_t *edge;
    unsigned *rowp;
    Value_t *rp;
    Value_t **reads;
    int nedges;
    int stateno;
    int symbol;
    int nwords;

    nwords = ngotos * tokensetsize;
    F = NEW2(nwords, unsigned);

    reads = NEW2(ngotos, Value_t *);
    edge = NEW2(ngotos + 1, Value_t);
    nedges = 0;

    rowp = F;
    for (i = 0; i < ngotos; i++)
    {
	stateno = to_state[i];
	sp = shift_table[stateno];

	if (sp)
	{
	    k = sp->nshifts;

	    for (j = 0; j < k; j++)
	    {
		symbol = accessing_symbol[sp->shift[j]];
		if (ISVAR(symbol))
		    break;
		SETBIT(rowp, symbol);
	    }

	    for (; j < k; j++)
	    {
		symbol = accessing_symbol[sp->shift[j]];
		if (nullable[symbol])
		    edge[nedges++] = map_goto(stateno, symbol);
	    }

	    if (nedges)
	    {
		reads[i] = rp = NEW2(nedges + 1, Value_t);

		for (j = 0; j < nedges; j++)
		    rp[j] = edge[j];

		rp[nedges] = -1;
		nedges = 0;
	    }
	}

	rowp += tokensetsize;
    }

    SETBIT(F, 0);
    digraph(reads);

    for (i = 0; i < ngotos; i++)
    {
	if (reads[i])
	    FREE(reads[i]);
    }

    FREE(reads);
    FREE(edge);
}
Beispiel #17
0
static void
build_relations(void)
{
    int i;
    int j;
    int k;
    Value_t *rulep;
    Value_t *rp;
    shifts *sp;
    int length;
    int nedges;
    int done_flag;
    Value_t state1;
    Value_t stateno;
    int symbol1;
    int symbol2;
    Value_t *shortp;
    Value_t *edge;
    Value_t *states;
    Value_t **new_includes;

    includes = NEW2(ngotos, Value_t *);
    edge = NEW2(ngotos + 1, Value_t);
    states = NEW2(maxrhs + 1, Value_t);

    for (i = 0; i < ngotos; i++)
    {
	nedges = 0;
	state1 = from_state[i];
	symbol1 = accessing_symbol[to_state[i]];

	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
	{
	    length = 1;
	    states[0] = state1;
	    stateno = state1;

	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
	    {
		symbol2 = *rp;
		sp = shift_table[stateno];
		k = sp->nshifts;

		for (j = 0; j < k; j++)
		{
		    stateno = sp->shift[j];
		    if (accessing_symbol[stateno] == symbol2)
			break;
		}

		states[length++] = stateno;
	    }

	    add_lookback_edge(stateno, *rulep, i);

	    length--;
	    done_flag = 0;
	    while (!done_flag)
	    {
		done_flag = 1;
		rp--;
		if (ISVAR(*rp))
		{
		    stateno = states[--length];
		    edge[nedges++] = map_goto(stateno, *rp);
		    if (nullable[*rp] && length > 0)
			done_flag = 0;
		}
	    }
	}

	if (nedges)
	{
	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
	    for (j = 0; j < nedges; j++)
		shortp[j] = edge[j];
	    shortp[nedges] = -1;
	}
    }

    new_includes = transpose(includes, ngotos);

    for (i = 0; i < ngotos; i++)
	if (includes[i])
	    FREE(includes[i]);

    FREE(includes);

    includes = new_includes;

    FREE(edge);
    FREE(states);
}
Beispiel #18
0
void
count_sr_conflicts (int state)
{
  register int i;
  register int k;
  register int mask;
  register shifts *shiftp;
  register unsigned *fp1;
  register unsigned *fp2;
  register unsigned *fp3;
  register int symbol;

  src_count = 0;

  shiftp = shift_table[state];
  if (!shiftp) return;

  for (i = 0; i < tokensetsize; i++)
    {
      shiftset[i] = 0;
      lookaheadset[i] = 0;
    }

  k = shiftp->nshifts;
  for (i = 0; i < k; i++)
    {
      if (! shiftp->shifts[i]) continue;
      symbol = accessing_symbol[shiftp->shifts[i]];
      if (ISVAR(symbol)) break;
      SETBIT(shiftset, symbol);
    }

  k = lookaheads[state + 1];
  fp3 = lookaheadset + tokensetsize;

  for (i = lookaheads[state]; i < k; i++)
    {
      fp1 = LA + i * tokensetsize;
      fp2 = lookaheadset;

      while (fp2 < fp3)
	*fp2++ |= *fp1++;
    }

  fp1 = shiftset;
  fp2 = lookaheadset;

  while (fp2 < fp3)
    *fp2++ &= *fp1++;

  mask = 1;
  fp2 = lookaheadset;
  for (i = 0; i < ntokens; i++)
    {
      if (mask & *fp2)
	src_count++;

      mask <<= 1;
      if (mask == 0)
	{
	  mask = 1;
	  fp2++;
	}
    }
}