Ejemplo n.º 1
0
static int
count_sr_conflicts (state *s)
{
  int i;
  int src_count = 0;
  transitions *trans = s->transitions;
  reductions *reds = s->reductions;

  if (!trans)
    return 0;

  bitset_zero (lookahead_set);
  bitset_zero (shift_set);

  FOR_EACH_SHIFT (trans, i)
    bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));

  for (i = 0; i < reds->num; ++i)
    bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);

  bitset_and (lookahead_set, lookahead_set, shift_set);

  src_count = bitset_count (lookahead_set);

  return src_count;
}
Ejemplo n.º 2
0
static rule *
state_default_rule (state *s)
{
  reductions *reds = s->reductions;
  rule *default_rule = NULL;
  int cmax = 0;
  int i;

  /* No need for a look-ahead.  */
  if (s->consistent)
    return reds->rules[0];

  /* 1. Each reduction is possibly masked by the look-ahead tokens on which
     we shift (S/R conflicts)...  */
  bitset_zero (shift_set);
  {
    transitions *trans = s->transitions;
    FOR_EACH_SHIFT (trans, i)
      {
	/* If this state has a shift for the error token, don't use a
	     default rule.  */
	if (TRANSITION_IS_ERROR (trans, i))
	  return NULL;
	bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
      }
  }

  /* 2. Each reduction is possibly masked by the look-ahead tokens on which
     we raise an error (due to %nonassoc).  */
  {
    errs *errp = s->errs;
    for (i = 0; i < errp->num; i++)
      if (errp->symbols[i])
	bitset_set (shift_set, errp->symbols[i]->number);
  }

  for (i = 0; i < reds->num; ++i)
    {
      int count = 0;

      /* How many non-masked look-ahead tokens are there for this
	 reduction?  */
      bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set);
      count = bitset_count (look_ahead_set);

      if (count > cmax)
	{
	  cmax = count;
	  default_rule = reds->rules[i];
	}

      /* 3. And finally, each reduction is possibly masked by previous
	 reductions (in R/R conflicts, we keep the first reductions).
	 */
      bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]);
    }

  return default_rule;
}
Ejemplo n.º 3
0
static void
inaccessable_symbols (void)
{
  bitset Vp, Vs, Pp;

  /* Find out which productions are reachable and which symbols are
     used.  Starting with an empty set of productions and a set of
     symbols which only has the start symbol in it, iterate over all
     productions until the set of productions remains unchanged for an
     iteration.  For each production which has a LHS in the set of
     reachable symbols, add the production to the set of reachable
     productions, and add all of the nonterminals in the RHS of the
     production to the set of reachable symbols.

     Consider only the (partially) reduced grammar which has only
     nonterminals in N and productions in P.

     The result is the set P of productions in the reduced grammar,
     and the set V of symbols in the reduced grammar.

     Although this algorithm also computes the set of terminals which
     are reachable, no terminal will be deleted from the grammar. Some
     terminals might not be in the grammar but might be generated by
     semantic routines, and so the user might want them available with
     specified numbers.  (Is this true?)  However, the nonreachable
     terminals are printed (if running in verbose mode) so that the
     user can know.  */

  Vp = bitset_create (nsyms, BITSET_FIXED);
  Pp = bitset_create (nrules, BITSET_FIXED);

  /* If the start symbol isn't useful, then nothing will be useful. */
  if (bitset_test (N, accept->number - ntokens))
    {
      bitset_set (V, accept->number);

      while (1)
        {
          rule_number r;
          bitset_copy (Vp, V);
          for (r = 0; r < nrules; r++)
            {
              if (!bitset_test (Pp, r)
                  && bitset_test (P, r)
                  && bitset_test (V, rules[r].lhs->number))
                {
                  item_number *rhsp;
                  for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
                    if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
                      bitset_set (Vp, *rhsp);
                  bitset_set (Pp, r);
                }
            }
          if (bitset_equal_p (V, Vp))
            break;
          Vs = Vp;
          Vp = V;
          V = Vs;
        }
    }

  bitset_free (V);
  V = Vp;

  /* Tokens 0, 1, and 2 are internal to Bison.  Consider them useful. */
  bitset_set (V, endtoken->number);             /* end-of-input token */
  bitset_set (V, errtoken->number);             /* error token */
  bitset_set (V, undeftoken->number);           /* some undefined token */

  bitset_free (P);
  P = Pp;

  nuseful_productions = bitset_count (P);
  nuseless_productions = nrules - nuseful_productions;

  nuseful_nonterminals = 0;
  {
    symbol_number i;
    for (i = ntokens; i < nsyms; i++)
      if (bitset_test (V, i))
        nuseful_nonterminals++;
  }
  nuseless_nonterminals = nvars - nuseful_nonterminals;

  /* A token that was used in %prec should not be warned about.  */
  {
    rule_number r;
    for (r = 0; r < nrules; ++r)
      if (rules[r].precsym != 0)
        bitset_set (V1, rules[r].precsym->number);
  }
}