mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-12 13:53:03 +00:00
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:
41
src/lalr.c
41
src/lalr.c
@@ -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;
|
||||
|
||||
29
src/print.c
29
src/print.c
@@ -1,7 +1,7 @@
|
||||
/* Print information on generated parser, for bison,
|
||||
|
||||
Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
13
src/reader.c
13
src/reader.c
@@ -1,7 +1,7 @@
|
||||
/* Input parser for Bison
|
||||
|
||||
Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003,
|
||||
2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
13
src/tables.c
13
src/tables.c
@@ -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. */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user