예제 #1
0
파일: ielr.c 프로젝트: Karavaykina/bison
/**
 * \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;
}
예제 #2
0
파일: LR0.c 프로젝트: a170785/buildroot
static void
save_reductions (state *s)
{
  int count = 0;
  size_t i;

  /* Find and count the active items that represent ends of rules. */
  for (i = 0; i < nitemset; ++i)
    {
      item_number item = ritem[itemset[i]];
      if (item_number_is_rule_number (item))
	{
	  rule_number r = item_number_as_rule_number (item);
	  redset[count++] = &rules[r];
	  if (r == 0)
	    {
	      /* This is "reduce 0", i.e., accept. */
	      aver (!final_state);
	      final_state = s;
	    }
	}
    }

  /* Make a reductions structure and copy the data into it.  */
  state_reductions_set (s, count, redset);
}
예제 #3
0
static void
print_core (FILE *out, int level, state *s)
{
  size_t i;
  item_number *sitems = s->items;
  size_t snritems = s->nitems;

  /* Output all the items of a state, not only its kernel.  */
  closure (sitems, snritems);
  sitems = itemset;
  snritems = nitemset;

  if (!snritems)
    {
      xml_puts (out, level, "<itemset/>");
      return;
    }

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

  for (i = 0; i < snritems; i++)
    {
      bool printed = false;
      item_number *sp1 = ritem + sitems[i];
      item_number *sp = sp1;
      rule *r;

      while (0 <= *sp)
        sp++;

      r = &rules[item_number_as_rule_number (*sp)];
      sp = r->rhs;

      /* Display the lookahead tokens?  */
      if (item_number_is_rule_number (*sp1))
        {
          reductions *reds = s->reductions;
          int red = state_reduction_find (s, r);
          /* Print item with lookaheads if there are. */
          if (reds->lookahead_tokens && red != -1)
            {
              xml_printf (out, level + 1,
                          "<item rule-number=\"%d\" point=\"%d\">",
                          r->number, sp1 - sp);
              state_rule_lookahead_tokens_print_xml (s, r,
                                                     out, level + 2);
              xml_puts (out, level + 1, "</item>");
              printed = true;
            }
        }

      if (!printed)
        xml_printf (out, level + 1,
                    "<item rule-number=\"%d\" point=\"%d\"/>",
                    r->number,
                    sp1 - sp);
    }
  xml_puts (out, level, "</itemset>");
}
예제 #4
0
static void
print_core (FILE *out, state *s)
{
  size_t i;
  item_number *sitems = s->items;
  size_t snritems = s->nitems;
  symbol *previous_lhs = NULL;

  /* Output all the items of a state, not only its kernel.  */
  if (report_flag & report_itemsets)
    {
      closure (sitems, snritems);
      sitems = itemset;
      snritems = nitemset;
    }

  if (!snritems)
    return;

  fputc ('\n', out);

  for (i = 0; i < snritems; i++)
    {
      item_number *sp;
      item_number *sp1;
      rule_number r;

      sp1 = sp = ritem + sitems[i];

      while (*sp >= 0)
	sp++;

      r = item_number_as_rule_number (*sp);

      rule_lhs_print (&rules[r], previous_lhs, out);
      previous_lhs = rules[r].lhs;

      for (sp = rules[r].rhs; sp < sp1; sp++)
	fprintf (out, " %s", symbols[*sp]->tag);
      fputs (" .", out);
      for (/* Nothing */; *sp >= 0; ++sp)
	fprintf (out, " %s", symbols[*sp]->tag);

      /* Display the lookahead tokens?  */
      if (report_flag & report_lookahead_tokens
          && item_number_is_rule_number (*sp1))
	state_rule_lookahead_tokens_print (s, &rules[r], out);

      fputc ('\n', out);
    }
}
예제 #5
0
파일: ielr.c 프로젝트: Karavaykina/bison
/**
 * \note
 *   - FIXME: It might be an interesting experiment to compare the space and
 *     time efficiency of computing \c item_lookahead_sets either:
 *     - Fully up front.
 *     - Just-in-time, as implemented below.
 *     - Not at all.  That is, just let annotations continue even when
 *       unnecessary.
 */
bool
ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
                         symbol_number lookahead, state ***predecessors,
                         bitset **item_lookahead_sets)
{
  if (!item_lookahead_sets[s->number])
    {
      size_t i;
      item_lookahead_sets[s->number] =
        xnmalloc (s->nitems, sizeof item_lookahead_sets[s->number][0]);
      for (i = 0; i < s->nitems; ++i)
        item_lookahead_sets[s->number][i] = NULL;
    }
  if (!item_lookahead_sets[s->number][item])
    {
      item_lookahead_sets[s->number][item] =
        bitset_create (ntokens, BITSET_FIXED);
      /* If this kernel item is the beginning of a RHS, it must be the kernel
         item in the start state, and so its LHS has no follows and no goto to
         check.  If, instead, this kernel item is the successor of the start
         state's kernel item, there are still no follows and no goto.  This
         situation is fortunate because we want to avoid the - 2 below in both
         cases.

         Actually, IELR(1) should never invoke this function for either of
         those cases because (1) follow_kernel_items will never reference a
         kernel item for this RHS because the end token blocks sight of the
         lookahead set from the RHS's only nonterminal, and (2) no reduction
         has a lookback dependency on this lookahead set.  Nevertheless, I
         didn't change this test to an aver just in case the usage of this
         function evolves to need those two cases.  In both cases, the current
         implementation returns the right result.  */
      if (s->items[item] > 1)
        {
          /* If the LHS symbol of this item isn't known (because this is a
             top-level invocation), go get it.  */
          if (!lhs)
            {
              unsigned int i;
              for (i = s->items[item];
                   !item_number_is_rule_number (ritem[i]);
                   ++i)
                ;
              lhs = rules[item_number_as_rule_number (ritem[i])].lhs->number;
            }
          /* If this kernel item is next to the beginning of the RHS, then
             check all predecessors' goto follows for the LHS.  */
          if (item_number_is_rule_number (ritem[s->items[item] - 2]))
            {
              state **predecessor;
              aver (lhs != accept->number);
              for (predecessor = predecessors[s->number];
                   *predecessor;
                   ++predecessor)
                bitset_or (item_lookahead_sets[s->number][item],
                           item_lookahead_sets[s->number][item],
                           goto_follows[map_goto ((*predecessor)->number,
                                                  lhs)]);
            }
          /* If this kernel item is later in the RHS, then check all
             predecessor items' lookahead sets.  */
          else
            {
              state **predecessor;
              for (predecessor = predecessors[s->number];
                   *predecessor;
                   ++predecessor)
                {
                  size_t predecessor_item;
                  for (predecessor_item = 0;
                       predecessor_item < (*predecessor)->nitems;
                       ++predecessor_item)
                    if ((*predecessor)->items[predecessor_item]
                        == s->items[item] - 1)
                      break;
                  aver (predecessor_item != (*predecessor)->nitems);
                  ielr_item_has_lookahead (*predecessor, lhs,
                                           predecessor_item, 0 /*irrelevant*/,
                                           predecessors, item_lookahead_sets);
                  bitset_or (item_lookahead_sets[s->number][item],
                             item_lookahead_sets[s->number][item],
                             item_lookahead_sets[(*predecessor)->number]
                                                [predecessor_item]);
                }
            }
        }
    }
  return bitset_test (item_lookahead_sets[s->number][item], lookahead);
}