/* Match rules with nonterminals for bison,

   Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2005 Free
   Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   Bison is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   Bison is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bison; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#include <config.h>
#include "system.h"

#include "getargs.h"

#include "derives.h"
#include "gram.h"
#include "reader.h"
#include "symtab.h"

/* Linked list of rule numbers.  */
typedef struct rule_list
{
  struct rule_list *next;
  rule *value;
} rule_list;

rule ***derives;

static void
print_derives (void)
{
  int i;

  fputs ("DERIVES\n", stderr);

  for (i = ntokens; i < nsyms; i++)
    {
      rule **rp;
      fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
      for (rp = derives[i - ntokens]; *rp; ++rp)
	{
	  fprintf (stderr, "\t\t%3d ", (*rp)->user_number);
	  rule_rhs_print (*rp, stderr);
	}
    }

  fputs ("\n\n", stderr);
}


void
derives_compute (void)
{
  symbol_number i;
  rule_number r;
  rule **q;

  /* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
     whose LHS is NTERM.  */
  rule_list **dset = xcalloc (nvars, sizeof *dset);

  /* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
     Instead of performing NRULES allocations for each, have an array
     indexed by rule numbers.  */
  rule_list *delts = xnmalloc (nrules, sizeof *delts);

  for (r = nrules - 1; r >= 0; --r)
    {
      symbol_number lhs = rules[r].lhs->number;
      rule_list *p = &delts[r];
      /* A new LHS is found.  */
      p->next = dset[lhs - ntokens];
      p->value = &rules[r];
      dset[lhs - ntokens] = p;
    }

  /* DSET contains what we need under the form of a linked list.  Make
     it a single array.  */

  derives = xnmalloc (nvars, sizeof *derives);
  q = xnmalloc (nvars + nrules, sizeof *q);

  for (i = ntokens; i < nsyms; i++)
    {
      rule_list *p = dset[i - ntokens];
      derives[i - ntokens] = q;
      while (p)
	{
	  *q++ = p->value;
	  p = p->next;
	}
      *q++ = NULL;
    }

  if (trace_flag & trace_sets)
    print_derives ();

  free (dset);
  free (delts);
}


void
derives_free (void)
{
  free (derives[0]);
  free (derives);
}
