Beispiel #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;
}
Beispiel #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;
}
Beispiel #3
0
/* Zero a vector of bitsets.  */
void
bitsetv_zero (bitsetv bsetv)
{
  bitset_bindex i;

  for (i = 0; bsetv[i]; i++)
    bitset_zero (bsetv[i]);
}
Beispiel #4
0
static void
no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
{
  int n;
  *no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
  bitset_zero (*no_reduce_set);
  FOR_EACH_SHIFT (s->transitions, n)
    bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
  for (n = 0; n < s->errs->num; ++n)
    if (s->errs->symbols[n])
      bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
}
Beispiel #5
0
static void
set_conflicts (state *s, symbol **errors)
{
  int i;
  transitions *trans = s->transitions;
  reductions *reds = s->reductions;
  int nerrs = 0;

  if (s->consistent)
    return;

  bitset_zero (lookahead_set);

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

  /* Loop over all rules which require lookahead in this state.  First
     check for shift-reduce conflict, and try to resolve using
     precedence.  */
  for (i = 0; i < reds->num; ++i)
    if (reds->rules[i]->prec && reds->rules[i]->prec->prec
	&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
      resolve_sr_conflict (s, i, errors, &nerrs);

  if (nerrs)
    {
      /* Some tokens have been explicitly made errors.  Allocate a
         permanent errs structure for this state, to record them.  */
      state_errs_set (s, nerrs, errors);
    }
  if (obstack_object_size (&solved_conflicts_obstack))
    {
      obstack_1grow (&solved_conflicts_obstack, '\0');
      s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
    }
  if (obstack_object_size (&solved_conflicts_xml_obstack))
    {
      obstack_1grow (&solved_conflicts_xml_obstack, '\0');
      s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack);
    }

  /* Loop over all rules which require lookahead in this state.  Check
     for conflicts not resolved above.  */
  for (i = 0; i < reds->num; ++i)
    {
      if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
	conflicts[s->number] = 1;
      bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
    }
}
Beispiel #6
0
static int
damap_addrset_flush_locked(damap_t *damapp)
{
	dam_t	*mapp = (dam_t *)damapp;
	int	idx;

	ASSERT(mapp);
	ASSERT(mutex_owned(&mapp->dam_lock));
	if (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) {
		return (DAM_EINVAL);
	}

	DTRACE_PROBE2(damap__addrset__flush__locked__enter,
	    char *, mapp->dam_name, dam_t *, mapp);
	if (mapp->dam_flags & DAM_SETADD) {
		DTRACE_PROBE2(damap__addrset__flush__locked__reset,
		    char *, mapp->dam_name, dam_t *, mapp);

		/*
		 * cancel stabilization timeout
		 */
		dam_sched_timeout(NULL, mapp, 0);
		DAM_INCR_STAT(mapp, dam_jitter);

		/*
		 * clear pending reports
		 */
		for (idx = 1; idx < mapp->dam_high; idx++) {
			if (DAM_IN_REPORT(mapp, idx)) {
				dam_addr_report_release(mapp, idx);
			}
		}

		bitset_zero(&mapp->dam_report_set);
		mapp->dam_flags &= ~DAM_SETADD;
		cv_signal(&mapp->dam_sync_cv);
	}
Beispiel #7
0
static void
print_reductions (FILE *out, int level, state *s)
{
  transitions *trans = s->transitions;
  reductions *reds = s->reductions;
  rule *default_reduction = NULL;
  int report = false;
  int i, j;

  if (reds->num == 0)
    {
      xml_puts (out, level, "<reductions/>");
      return;
    }

  if (yydefact[s->number] != 0)
    default_reduction = &rules[yydefact[s->number] - 1];

  bitset_zero (no_reduce_set);
  FOR_EACH_SHIFT (trans, i)
    bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
  for (i = 0; i < s->errs->num; ++i)
    if (s->errs->symbols[i])
      bitset_set (no_reduce_set, s->errs->symbols[i]->number);

  if (default_reduction)
    report = true;

  if (reds->lookahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
        bool count = bitset_test (no_reduce_set, i);

        for (j = 0; j < reds->num; ++j)
          if (bitset_test (reds->lookahead_tokens[j], i))
            {
              if (! count)
                {
                  if (reds->rules[j] != default_reduction)
                    report = true;
                  count = true;
                }
              else
                {
                  report = true;
                }
            }
      }

  /* Nothing to report. */
  if (!report)
    {
      xml_puts (out, level, "<reductions/>");
      return;
    }

  xml_puts (out, level, "<reductions>");

  /* Report lookahead tokens (or $default) and reductions.  */
  if (reds->lookahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
        bool defaulted = false;
        bool count = bitset_test (no_reduce_set, i);

        for (j = 0; j < reds->num; ++j)
          if (bitset_test (reds->lookahead_tokens[j], i))
            {
              if (! count)
                {
                  if (reds->rules[j] != default_reduction)
                    print_reduction (out, level + 1, symbols[i]->tag,
                                     reds->rules[j], true);
                  else
                    defaulted = true;
                  count = true;
                }
              else
                {
                  if (defaulted)
                    print_reduction (out, level + 1, symbols[i]->tag,
                                     default_reduction, true);
                  defaulted = false;
                  print_reduction (out, level + 1, symbols[i]->tag,
                                   reds->rules[j], false);
                }
            }
      }

  if (default_reduction)
    print_reduction (out, level + 1,
                     "$default", default_reduction, true);

  xml_puts (out, level, "</reductions>");
}
Beispiel #8
0
/**
 * \pre:
 *   - \c ritem_sees_lookahead_set was computed by
 *     \c ielr_compute_ritem_sees_lookahead_set.
 * \post:
 *   - Each of \c *edgesp and \c *edge_countsp is a new array of size
 *     \c ::ngotos.
 *   - <tt>(*edgesp)[i]</tt> points to a \c goto_number array of size
 *     <tt>(*edge_countsp)[i]+1</tt>.
 *   - In such a \c goto_number array, the last element is \c ::END_NODE.
 *   - All remaining elements are the indices of the gotos to which there is an
 *     internal follow edge from goto \c i.
 *   - There is an internal follow edge from goto \c i to goto \c j iff both:
 *     - The from states of gotos \c i and \c j are the same.
 *     - The transition nonterminal for goto \c i appears as the first RHS
 *       symbol of at least one production for which both:
 *       - The LHS is the transition symbol of goto \c j.
 *       - All other RHS symbols are nullable nonterminals.
 *     - In other words, the follows of goto \c i include the follows of
 *       goto \c j and it's an internal edge because the from states are the
 *       same.
 */
static void
ielr_compute_internal_follow_edges (bitset ritem_sees_lookahead_set,
                                    goto_number ***edgesp, int **edge_countsp)
{
  *edgesp = xnmalloc (ngotos, sizeof **edgesp);
  *edge_countsp = xnmalloc (ngotos, sizeof **edge_countsp);
  {
    bitset sources = bitset_create (ngotos, BITSET_FIXED);
    goto_number i;
    for (i = 0; i < ngotos; ++i)
      (*edge_countsp)[i] = 0;
    for (i = 0; i < ngotos; ++i)
      {
        int nsources = 0;
        {
          rule **rulep;
          for (rulep = derives[states[to_state[i]]->accessing_symbol
                               - ntokens];
               *rulep;
               ++rulep)
            {
              /* If there is at least one RHS symbol, if the first RHS symbol
                 is a nonterminal, and if all remaining RHS symbols (if any)
                 are nullable nonterminals, create an edge from the LHS
                 symbol's goto to the first RHS symbol's goto such that the RHS
                 symbol's goto will be the source of the edge after the
                 eventual relation_transpose below.

                 Unlike in ielr_compute_always_follows, I use a bitset for
                 edges rather than an array because it is possible that
                 multiple RHS's with the same first symbol could fit and thus
                 that we could end up with redundant edges.  With the
                 possibility of redundant edges, it's hard to know ahead of
                 time how large to make such an array.  Another possible
                 redundancy is that source and destination might be the same
                 goto.  Eliminating all these possible redundancies now might
                 possibly help performance a little.  I have not proven any of
                 this, but I'm guessing the bitset shouldn't entail much of a
                 performance penalty, if any.  */
              if (bitset_test (ritem_sees_lookahead_set,
                               (*rulep)->rhs - ritem))
                {
                  goto_number source =
                    map_goto (from_state[i],
                              item_number_as_symbol_number (*(*rulep)->rhs));
                  if (i != source && !bitset_test (sources, source))
                    {
                      bitset_set (sources, source);
                      ++nsources;
                      ++(*edge_countsp)[source];
                    }
                }
            }
        }
        if (nsources == 0)
          (*edgesp)[i] = NULL;
        else
          {
            (*edgesp)[i] = xnmalloc (nsources + 1, sizeof *(*edgesp)[i]);
            {
              bitset_iterator biter_source;
              bitset_bindex source;
              int j = 0;
              BITSET_FOR_EACH (biter_source, sources, source, 0)
                (*edgesp)[i][j++] = source;
            }
            (*edgesp)[i][nsources] = END_NODE;
          }
        bitset_zero (sources);
      }
    bitset_free (sources);
  }

  relation_transpose (edgesp, ngotos);

  if (trace_flag & trace_ielr)
    {
      fprintf (stderr, "internal_follow_edges:\n");
      relation_print (*edgesp, ngotos, stderr);
    }
}
Beispiel #9
0
static void
print_reductions (FILE *out, state *s)
{
  transitions *trans = s->transitions;
  reductions *reds = s->reductions;
  rule *default_rule = NULL;
  size_t width = 0;
  int i, j;

  if (reds->num == 0)
    return;

  default_rule = state_default_rule (s);

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

  /* Compute the width of the look-ahead token column.  */
  if (default_rule)
    width = strlen (_("$default"));

  if (reds->look_ahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
	bool count = bitset_test (shift_set, i);

	for (j = 0; j < reds->num; ++j)
	  if (bitset_test (reds->look_ahead_tokens[j], i))
	    {
	      if (! count)
		{
		  if (reds->rules[j] != default_rule)
		    max_length (&width, symbols[i]->tag);
		  count = true;
		}
	      else
		{
		  max_length (&width, symbols[i]->tag);
		}
	    }
      }

  /* Nothing to report. */
  if (!width)
    return;

  fputc ('\n', out);
  width += 2;

  /* Report look-ahead tokens (or $default) and reductions.  */
  if (reds->look_ahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
	bool defaulted = false;
	bool count = bitset_test (shift_set, i);

	for (j = 0; j < reds->num; ++j)
	  if (bitset_test (reds->look_ahead_tokens[j], i))
	    {
	      if (! count)
		{
		  if (reds->rules[j] != default_rule)
		    print_reduction (out, width,
				     symbols[i]->tag,
				     reds->rules[j], true);
		  else
		    defaulted = true;
		  count = true;
		}
	      else
		{
		  if (defaulted)
		    print_reduction (out, width,
				     symbols[i]->tag,
				     default_rule, true);
		  defaulted = false;
		  print_reduction (out, width,
				   symbols[i]->tag,
				   reds->rules[j], false);
		}
	    }
      }

  if (default_rule)
    print_reduction (out, width,
		     _("$default"), default_rule, true);
}
Beispiel #10
0
static void
print_reductions (FILE *out, state *s)
{
  transitions *trans = s->transitions;
  reductions *reds = s->reductions;
  rule *default_reduction = NULL;
  size_t width = 0;
  int i, j;
  bool default_reduction_only = true;

  if (reds->num == 0)
    return;

  if (yydefact[s->number] != 0)
    default_reduction = &rules[yydefact[s->number] - 1];

  bitset_zero (no_reduce_set);
  FOR_EACH_SHIFT (trans, i)
    bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
  for (i = 0; i < s->errs->num; ++i)
    if (s->errs->symbols[i])
      bitset_set (no_reduce_set, s->errs->symbols[i]->number);

  /* Compute the width of the lookahead token column.  */
  if (default_reduction)
    width = strlen (_("$default"));

  if (reds->lookahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
	bool count = bitset_test (no_reduce_set, i);

	for (j = 0; j < reds->num; ++j)
	  if (bitset_test (reds->lookahead_tokens[j], i))
	    {
	      if (! count)
		{
		  if (reds->rules[j] != default_reduction)
		    max_length (&width, symbols[i]->tag);
		  count = true;
		}
	      else
		{
		  max_length (&width, symbols[i]->tag);
		}
	    }
      }

  /* Nothing to report. */
  if (!width)
    return;

  fputc ('\n', out);
  width += 2;

  /* Report lookahead tokens (or $default) and reductions.  */
  if (reds->lookahead_tokens)
    for (i = 0; i < ntokens; i++)
      {
	bool defaulted = false;
	bool count = bitset_test (no_reduce_set, i);
        if (count)
          default_reduction_only = false;

	for (j = 0; j < reds->num; ++j)
	  if (bitset_test (reds->lookahead_tokens[j], i))
	    {
	      if (! count)
		{
		  if (reds->rules[j] != default_reduction)
                    {
                      default_reduction_only = false;
                      print_reduction (out, width,
                                       symbols[i]->tag,
                                       reds->rules[j], true);
                    }
		  else
		    defaulted = true;
		  count = true;
		}
	      else
		{
                  default_reduction_only = false;
		  if (defaulted)
		    print_reduction (out, width,
				     symbols[i]->tag,
				     default_reduction, true);
		  defaulted = false;
		  print_reduction (out, width,
				   symbols[i]->tag,
				   reds->rules[j], false);
		}
	    }
      }

  if (default_reduction)
    {
      char *default_reductions =
        muscle_percent_define_get ("lr.default-reductions");
      print_reduction (out, width, _("$default"), default_reduction, true);
      aver (0 == strcmp (default_reductions, "most")
            || (0 == strcmp (default_reductions, "consistent")
                && default_reduction_only)
            || (reds->num == 1 && reds->rules[0]->number == 0));
      free (default_reductions);
    }
}