X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/76290368d48b584808a120dfbd415be93aef04f6..ba4184ec9152422c14be743e876b5716daf0aa80:/src/reader.c?ds=inline
diff --git a/src/reader.c b/src/reader.c
index ce23f48c..3f224bf5 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -1,28 +1,27 @@
/* Input parser for Bison
Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003,
- 2005, 2006 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2009 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
+ This program 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.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- Bison is distributed in the hope that it will be useful,
+ This program 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. */
+ along with this program. If not, see . */
#include
#include "system.h"
+#include
#include
#include "complain.h"
@@ -30,7 +29,7 @@
#include "files.h"
#include "getargs.h"
#include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
#include "reader.h"
#include "symlist.h"
#include "symtab.h"
@@ -69,27 +68,6 @@ grammar_start_symbol_set (symbol *sym, location loc)
}
}
-
-/*---------------------------------------------------------------------.
-| There are two prologues: one before the first %union and one after. |
-| Augment the one specified by POST. |
-`---------------------------------------------------------------------*/
-
-void
-prologue_augment (const char *prologue, location loc, bool post)
-{
- struct obstack *oout =
- !post ? &pre_prologue_obstack : &post_prologue_obstack;
-
- obstack_fgrow1 (oout, "]b4_syncline(%d, [[", loc.start.line);
- /* FIXME: Protection of M4 characters missing here. See
- output.c:escaped_output. */
- MUSCLE_OBSTACK_SGROW (oout,
- quotearg_style (c_quoting_style, loc.start.file));
- obstack_sgrow (oout, "]])[\n");
- obstack_sgrow (oout, prologue);
-}
-
/*------------------------------------------------------------------------.
@@ -192,7 +170,7 @@ free_merger_functions (void)
static symbol_list *grammar_end = NULL;
/* Append SYM to the grammar. */
-static void
+static symbol_list *
grammar_symbol_append (symbol *sym, location loc)
{
symbol_list *p = symbol_list_sym_new (sym, loc);
@@ -208,8 +186,27 @@ grammar_symbol_append (symbol *sym, location loc)
part of it. */
if (sym)
++nritems;
+
+ return p;
}
+static void
+assign_named_ref (symbol_list *p, named_ref *name)
+{
+ symbol *sym = p->content.sym;
+
+ if (name->id == sym->tag)
+ {
+ warn_at (name->loc,
+ _("duplicated symbol name for %s ignored"),
+ quote (sym->tag));
+ named_ref_free (name);
+ }
+ else
+ p->named_ref = name;
+}
+
+
/* The rule currently being defined, and the previous rule.
CURRENT_RULE points to the first LHS of the current rule, while
PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */
@@ -222,12 +219,19 @@ static symbol_list *previous_rule_end = NULL;
`----------------------------------------------*/
void
-grammar_current_rule_begin (symbol *lhs, location loc)
+grammar_current_rule_begin (symbol *lhs, location loc,
+ named_ref *lhs_name)
{
+ symbol_list* p;
+
/* Start a new rule and record its lhs. */
++nrules;
previous_rule_end = grammar_end;
- grammar_symbol_append (lhs, loc);
+
+ p = grammar_symbol_append (lhs, loc);
+ if (lhs_name)
+ assign_named_ref(p, lhs_name);
+
current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */
@@ -253,21 +257,14 @@ grammar_current_rule_begin (symbol *lhs, location loc)
static bool
symbol_should_be_used (symbol_list const *s)
{
- if (code_props_code_get (symbol_destructor_get (s->content.sym)))
+ if (symbol_destructor_get (s->content.sym)->code)
return true;
if (warnings_flag & warnings_midrule_values)
- {
- if (s->midrule && code_props_is_value_used (s->midrule->action_props))
- return true;
- if (s->midrule_parent_rule)
- {
- symbol_list *rhs_node =
- symbol_list_n_get (s->midrule_parent_rule,
- s->midrule_parent_rhs_index);
- if (code_props_is_value_used (rhs_node->action_props))
- return true;
- }
- }
+ return ((s->midrule && s->midrule->action_props.is_value_used)
+ || (s->midrule_parent_rule
+ && symbol_list_n_get (s->midrule_parent_rule,
+ s->midrule_parent_rhs_index)
+ ->action_props.is_value_used));
return false;
}
@@ -286,7 +283,7 @@ grammar_rule_check (const symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */
- if (!code_props_code_get (r->action_props) && r->content.sym->type_name)
+ if (!r->action_props.code && r->content.sym->type_name)
{
symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */
@@ -311,11 +308,10 @@ grammar_rule_check (const symbol_list *r)
symbol_list const *l = r;
int n = 0;
for (; l && l->content.sym; l = l->next, ++n)
- if (! (code_props_is_value_used (l->action_props)
+ if (! (l->action_props.is_value_used
|| !symbol_should_be_used (l)
/* The default action, $$ = $1, `uses' both. */
- || (!code_props_code_get (r->action_props)
- && (n == 0 || n == 1))))
+ || (!r->action_props.code && (n == 0 || n == 1))))
{
if (n)
warn_at (r->location, _("unused value: $%d"), n);
@@ -355,22 +351,23 @@ grammar_midrule_action (void)
/* Make a DUMMY nonterminal, whose location is that of the midrule
action. Create the MIDRULE. */
- location dummy_location =
- code_props_location_get (current_rule->action_props);
+ location dummy_location = current_rule->action_props.location;
symbol *dummy = dummy_symbol_get (dummy_location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
+ /* Remember named_ref of previous action. */
+ named_ref *action_name = current_rule->action_props.named_ref;
+
/* Make a new rule, whose body is empty, before the current one, so
that the action just read can belong to it. */
++nrules;
++nritems;
/* Attach its location and actions to that of the DUMMY. */
midrule->location = dummy_location;
- code_props_rule_action_init (
- &midrule->action_props,
- code_props_code_get (current_rule->action_props),
- code_props_location_get (current_rule->action_props),
- midrule);
+ code_props_rule_action_init (&midrule->action_props,
+ current_rule->action_props.code,
+ current_rule->action_props.location,
+ midrule, 0);
code_props_none_init (¤t_rule->action_props);
if (previous_rule_end)
@@ -386,7 +383,8 @@ grammar_midrule_action (void)
/* Insert the dummy nonterminal replacing the midrule action into
the current rule. Bind it to its dedicated rule. */
- grammar_current_rule_symbol_append (dummy, dummy_location);
+ grammar_current_rule_symbol_append (dummy, dummy_location,
+ action_name);
grammar_end->midrule = midrule;
midrule->midrule_parent_rule = current_rule;
midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
@@ -397,6 +395,7 @@ grammar_midrule_action (void)
void
grammar_current_rule_prec_set (symbol *precsym, location loc)
{
+ symbol_class_set (precsym, token_sym, loc, false);
if (current_rule->ruleprec)
complain_at (loc, _("only one %s allowed per rule"), "%prec");
current_rule->ruleprec = precsym;
@@ -434,24 +433,29 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
action as a mid-rule action. */
void
-grammar_current_rule_symbol_append (symbol *sym, location loc)
+grammar_current_rule_symbol_append (symbol *sym, location loc,
+ named_ref *name)
{
- if (code_props_code_get (current_rule->action_props))
+ symbol_list *p;
+ if (current_rule->action_props.code)
grammar_midrule_action ();
- grammar_symbol_append (sym, loc);
+ p = grammar_symbol_append (sym, loc);
+ if (name)
+ assign_named_ref(p, name);
}
/* Attach an ACTION to the current rule. */
void
-grammar_current_rule_action_append (const char *action, location loc)
+grammar_current_rule_action_append (const char *action, location loc,
+ named_ref *name)
{
- if (code_props_code_get (current_rule->action_props))
+ if (current_rule->action_props.code)
grammar_midrule_action ();
/* After all symbol declarations have been parsed, packgram invokes
code_props_translate_code. */
code_props_rule_action_init (¤t_rule->action_props, action, loc,
- current_rule);
+ current_rule, name);
}
@@ -474,20 +478,6 @@ packgram (void)
rules = xnmalloc (nrules, sizeof *rules);
- /* Before invoking grammar_rule_check on any rule, make sure all actions have
- already been scanned in order to set `used' flags. Otherwise, checking
- that a midrule's $$ should be set will not always work properly because
- the check must forward-reference the midrule's parent rule. For the same
- reason, all the `used' flags must be set before checking whether to remove
- `$' from any midrule symbol name. */
- while (p)
- {
- code_props_translate_code (&p->action_props);
- if (p)
- p = p->next;
- }
-
- p = grammar;
while (p)
{
int rule_length = 0;
@@ -504,20 +494,17 @@ packgram (void)
rules[ruleno].precsym = NULL;
rules[ruleno].location = p->location;
rules[ruleno].useful = true;
- rules[ruleno].action = code_props_code_get (p->action_props);
- if (rules[ruleno].action)
- rules[ruleno].action_location =
- code_props_location_get (p->action_props);
+ rules[ruleno].action = p->action_props.code;
+ rules[ruleno].action_location = p->action_props.location;
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
symbol name so that it's a user-defined symbol so that the default
%destructor and %printer apply. */
if (p->midrule_parent_rule
- && (code_props_is_value_used (p->action_props)
- || code_props_is_value_used (
- symbol_list_n_get (
- p->midrule_parent_rule,
- p->midrule_parent_rhs_index)->action_props)))
+ && (p->action_props.is_value_used
+ || symbol_list_n_get (p->midrule_parent_rule,
+ p->midrule_parent_rhs_index)
+ ->action_props.is_value_used))
p->content.sym->tag += 1;
/* Don't check the generated rule 0. It has no action, so some rhs
@@ -597,10 +584,6 @@ reader (void)
undeftoken->class = token_sym;
undeftoken->number = ntokens++;
- /* Initialize the obstacks. */
- obstack_init (&pre_prologue_obstack);
- obstack_init (&post_prologue_obstack);
-
gram_in = xfopen (grammar_file, "r");
gram__flex_debug = trace_flag & trace_scan;
@@ -608,6 +591,31 @@ reader (void)
gram_scanner_initialize ();
gram_parse ();
+ /* Set front-end %define variable defaults. */
+ muscle_percent_define_default ("lr.keep-unreachable-states", "false");
+ {
+ char *lr_type;
+ /* IELR would be a better default, but LALR is historically the
+ default. */
+ muscle_percent_define_default ("lr.type", "LALR");
+ lr_type = muscle_percent_define_get ("lr.type");
+ if (0 != strcmp (lr_type, "canonical LR"))
+ muscle_percent_define_default ("lr.default-reductions", "all");
+ else
+ muscle_percent_define_default ("lr.default-reductions", "accepting");
+ free (lr_type);
+ }
+
+ /* Check front-end %define variables. */
+ {
+ static char const * const values[] = {
+ "lr.type", "LALR", "IELR", "canonical LR", NULL,
+ "lr.default-reductions", "all", "consistent", "accepting", NULL,
+ NULL
+ };
+ muscle_percent_define_check_values (values);
+ }
+
if (! complaint_issued)
check_and_convert_grammar ();
@@ -680,6 +688,23 @@ check_and_convert_grammar (void)
token symbols into FDEFINES if requested. */
symbols_pack ();
+ /* Scan rule actions after invoking symbol_check_alias_consistency (in
+ symbols_pack above) so that token types are set correctly before the rule
+ action type checking.
+
+ Before invoking grammar_rule_check (in packgram below) on any rule, make
+ sure all actions have already been scanned in order to set `used' flags.
+ Otherwise, checking that a midrule's $$ should be set will not always work
+ properly because the check must forward-reference the midrule's parent
+ rule. For the same reason, all the `used' flags must be set before
+ checking whether to remove `$' from any midrule symbol name (also in
+ packgram). */
+ {
+ symbol_list *sym;
+ for (sym = grammar; sym; sym = sym->next)
+ code_props_translate_code (&sym->action_props);
+ }
+
/* Convert the grammar into the format described in gram.h. */
packgram ();