On Wed, September 16, 2009 16:32, Akim Demaille wrote:

>>> It would be nice to extend the *.output file with various metrics
>>> about the grammar.
>>
>> Agreed.
>
> Will add this to TODO.
About this metrics feature: there is a patched bison version
with a metrics option added. it is at "Ambiguity detection in GNU Bison"
http://www.lsv.ens-cachan.fr/~schmitz/software
there are some test grammars and documentation and cannot
test this feature because the bison-2.3a+ambiguity.tar.bz2
does not compile for some reason.
the source for metrics is in metrics.c

/* 
   Copyright (C) 2006
   Laboratoire I3S, Université de Nice-Sophia Antipolis & CNRS.

   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.  */
/**
 * \file metrics.c
 * \brief Grammar metrics computations.
 */
#include <config.h>
#include "system.h"
#include <math.h>
#include "gram.h"
#include "derives.h"
#include "metrics.h"
#include "sets.h"

/** Returns the McCabe complexity of the grammar.  In a bison grammar,
    this boils down to counting the number of alternance signs \c
    |.
    \pre #derives_counts was computed. */
inline static unsigned int
mcc (void)
{
  unsigned int i, ret = 0;

  for (i = 0; i < nvars; i++)
    ret += (derives_counts[i])? derives_counts[i] - 1: 0;

  return ret;
}

/** Compute the number of LR(1) positions.
    \pre #derives has been computed.
    \pre #follow_tokens has been computed. */
inline static unsigned int
lr1_npositions (void)
{
  unsigned int i, j, ret = 0;

  for (i = 0; i < nvars; i++)
    {
      unsigned int f = bitset_count (follow_tokens[i]);
      ret += 2 * f;
      for (j = 0; derives[i][j]; j++)
        ret += f * (rule_rhs_length (derives[i][j]) + 1);
    }

  return ret;
}

inline void 
grammar_metrics (FILE *out)
{
  unsigned int nlr1 = lr1_npositions ();
  double npairs = (double)nlr1 * (double)(nlr1 + 1) * 2;
  fprintf (out, "Grammar metrics.\n");
  fprintf (out, "\tsize |G|:\t\t%u\n", nritems);
  fprintf (out, "\tterminals |T|:\t\t%u\n", ntokens);
  fprintf (out, "\tnonterminals |N|:\t%u\n", nvars);
  fprintf (out, "\tvocabulary |V|:\t\t%u\n", nsyms);
  fprintf (out, "\tproductions |P|:\t%u\n", nrules);
  fprintf (out, "\tnorm ||G||:\t\t%.2f\n", nritems * log (nsyms) / M_LN2);
  fprintf (out, "\tMcCabe complexity MCC:\t%u\n", mcc ());
  fprintf (out, "\taverage rhs length AVS:\t%.2f\n",
           (double)nritems / (double)nrules);
  fprintf (out, "\tLR(1) positions:\t%u\n", nlr1);
  fprintf (out, "\tmax LR(1) pairs:\t%.3e\n", npairs);
  fprintf (out, "\n");
}

Reply via email to