Implement %define lr.default_rules.

Its value describes the states that are permitted to contain
default rules: "all", "consistent", or "accepting".
* src/reader.c (reader): Default lr.default_rules to "all".
Check for a valid lr.default_rules value.
* src/lalr.c (state_lookahead_tokens_count): If lr.default_rules
is "accepting", then only mark the accepting state as
consistent.
(initialize_LA): Tell state_lookahead_tokens_count whether
lr.default_rules is "accepting".
* src/tables.c (action_row): If lr.default_rules is not "all",
then disable default rules in inconsistent states.
* src/print.c (print_reductions): Use this opportunity to
perform some assertions about whether lr.default_rules was
obeyed correctly.
* tests/local.at (AT_TEST_TABLES_AND_PARSE): New macro that
helps with checking the parser tables for a grammar.
* tests/input.at (%define lr.default_rules invalid values): New
test group.
* tests/reduce.at (AT_TEST_LR_DEFAULT_RULES): New macro using
AT_TEST_TABLES_AND_PARSE.
(`no %define lr.default_rules'): New test group generated by
AT_TEST_LR_DEFAULT_RULES.
(`%define lr.default_rules "all"'): Likewise.
(`%define lr.default_rules "consistent"'): Likewise.
(`%define lr.default_rules "accepting"'): Likewise.
This commit is contained in:
Joel E. Denny
2009-04-20 00:55:50 -04:00
parent 72e727f2ec
commit 7254f6a840
8 changed files with 428 additions and 22 deletions

View File

@@ -1,7 +1,7 @@
/* Compute lookahead criteria for Bison.
Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007 Free Software Foundation, Inc.
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -36,6 +36,7 @@
#include "getargs.h"
#include "gram.h"
#include "lalr.h"
#include "muscle-tab.h"
#include "nullable.h"
#include "reader.h"
#include "relation.h"
@@ -336,22 +337,30 @@ compute_lookahead_tokens (void)
`----------------------------------------------------*/
static int
state_lookahead_tokens_count (state *s)
state_lookahead_tokens_count (state *s, bool default_rule_only_for_accept)
{
int n_lookahead_tokens = 0;
reductions *rp = s->reductions;
transitions *sp = s->transitions;
/* We need a lookahead either to distinguish different
reductions (i.e., there are two or more), or to distinguish a
reduction from a shift. Otherwise, it is straightforward,
and the state is `consistent'. There is no need to check that
transition 0 hasn't been disabled before checking if it is a
shift since transitions are only disabled during conflict
resolution, and that hasn't happened yet. */
/* Transitions are only disabled during conflict resolution, and that
hasn't happened yet, so there should be no need to check that
transition 0 hasn't been disabled before checking if it is a shift.
However, this check was performed at one time, so we leave it as an
aver. */
aver (sp->num == 0 || !TRANSITION_IS_DISABLED (sp, 0));
/* We need a lookahead either to distinguish different reductions
(i.e., there are two or more), or to distinguish a reduction from a
shift. Otherwise, it is straightforward, and the state is
`consistent'. However, for states that have any rules, treat only
the accepting state as consistent (since there is never a lookahead
token that makes sense there, and so no lookahead token should be
read) if the user has otherwise disabled default rules. */
if (rp->num > 1
|| (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0)))
|| (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0))
|| (rp->num == 1 && rp->rules[0]->number != 0
&& default_rule_only_for_accept))
n_lookahead_tokens += rp->num;
else
s->consistent = 1;
@@ -369,11 +378,18 @@ initialize_LA (void)
{
state_number i;
bitsetv pLA;
bool default_rule_only_for_accept;
{
char *default_rules = muscle_percent_define_get ("lr.default_rules");
default_rule_only_for_accept = 0 == strcmp (default_rules, "accepting");
free (default_rules);
}
/* Compute the total number of reductions requiring a lookahead. */
nLA = 0;
for (i = 0; i < nstates; i++)
nLA += state_lookahead_tokens_count (states[i]);
nLA +=
state_lookahead_tokens_count (states[i], default_rule_only_for_accept);
/* Avoid having to special case 0. */
if (!nLA)
nLA = 1;
@@ -385,7 +401,8 @@ initialize_LA (void)
require lookahead tokens. */
for (i = 0; i < nstates; i++)
{
int count = state_lookahead_tokens_count (states[i]);
int count =
state_lookahead_tokens_count (states[i], default_rule_only_for_accept);
if (count)
{
states[i]->reductions->lookahead_tokens = pLA;

View File

@@ -1,7 +1,7 @@
/* Print information on generated parser, for bison,
Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009
Free Software Foundation, Inc.
Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005,
2007, 2009 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -31,6 +31,7 @@
#include "getargs.h"
#include "gram.h"
#include "lalr.h"
#include "muscle-tab.h"
#include "print.h"
#include "reader.h"
#include "reduce.h"
@@ -244,6 +245,7 @@ print_reductions (FILE *out, state *s)
rule *default_rule = NULL;
size_t width = 0;
int i, j;
bool non_default_action = false;
if (reds->num == 0)
return;
@@ -296,6 +298,8 @@ print_reductions (FILE *out, state *s)
{
bool defaulted = false;
bool count = bitset_test (no_reduce_set, i);
if (count)
non_default_action = true;
for (j = 0; j < reds->num; ++j)
if (bitset_test (reds->lookahead_tokens[j], i))
@@ -303,15 +307,19 @@ print_reductions (FILE *out, state *s)
if (! count)
{
if (reds->rules[j] != default_rule)
print_reduction (out, width,
symbols[i]->tag,
reds->rules[j], true);
{
non_default_action = true;
print_reduction (out, width,
symbols[i]->tag,
reds->rules[j], true);
}
else
defaulted = true;
count = true;
}
else
{
non_default_action = true;
if (defaulted)
print_reduction (out, width,
symbols[i]->tag,
@@ -325,8 +333,15 @@ print_reductions (FILE *out, state *s)
}
if (default_rule)
print_reduction (out, width,
_("$default"), default_rule, true);
{
char *default_rules = muscle_percent_define_get ("lr.default_rules");
print_reduction (out, width, _("$default"), default_rule, true);
aver (0 == strcmp (default_rules, "all")
|| (0 == strcmp (default_rules, "consistent")
&& !non_default_action)
|| (reds->num == 1 && reds->rules[0]->number == 0));
free (default_rules);
}
}

View File

@@ -555,6 +555,17 @@ reader (void)
gram_scanner_initialize ();
gram_parse ();
muscle_percent_define_default ("lr.default_rules", "all");
/* Check front-end %define variable values. */
{
static char const * const values[] = {
"lr.default_rules", "all", "consistent", "accepting", NULL,
NULL
};
muscle_percent_define_check_values (values);
}
if (! complaint_issued)
check_and_convert_grammar ();

View File

@@ -1,7 +1,7 @@
/* Output the generated parsing program for Bison.
Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
2005, 2006 Free Software Foundation, Inc.
2005, 2006, 2009 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -30,6 +30,7 @@
#include "getargs.h"
#include "gram.h"
#include "lalr.h"
#include "muscle-tab.h"
#include "reader.h"
#include "symtab.h"
#include "tables.h"
@@ -303,6 +304,16 @@ action_row (state *s)
actrow[sym->number] = ACTION_NUMBER_MINIMUM;
}
/* Turn off default rules where requested by the user. See
state_lookahead_tokens_count in lalr.c to understand when states are
labeled as consistent. */
{
char *default_rules = muscle_percent_define_get ("lr.default_rules");
if (0 != strcmp (default_rules, "all") && !s->consistent)
nodefault = true;
free (default_rules);
}
/* Now find the most common reduction and make it the default action
for this state. */