X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/23ec25b7c6c4eb587a5fa832f67765a6143b7925..93d133c932a4f754172cd8473bfe469975b00023:/src/reader.c?ds=inline diff --git a/src/reader.c b/src/reader.c index 8a292b8a..86fde7b2 100644 --- a/src/reader.c +++ b/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, 2009 Free Software Foundation, Inc. + Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007, + 2009-2012 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -22,7 +22,6 @@ #include "system.h" #include -#include #include "complain.h" #include "conflicts.h" @@ -129,12 +128,16 @@ record_merge_function_type (int merger, uniqstr type, location declaration_loc) aver (merge_function != NULL && merger_find == merger); if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type)) { - complain_at (declaration_loc, - _("result type clash on merge function `%s': <%s> != <%s>"), - merge_function->name, type, merge_function->type); - complain_at (merge_function->type_declaration_location, - _("previous declaration")); - } + unsigned indent = 0; + complain_at_indent (declaration_loc, &indent, + _("result type clash on merge function %s: " + "<%s> != <%s>"), + quote (merge_function->name), type, + merge_function->type); + indent += SUB_INDENT; + complain_at_indent (merge_function->type_declaration_location, &indent, + _("previous declaration")); + } merge_function->type = uniqstr_new (type); merge_function->type_declaration_location = declaration_loc; } @@ -231,7 +234,7 @@ grammar_current_rule_begin (symbol *lhs, location loc, p = grammar_symbol_append (lhs, loc); if (lhs_name) - assign_named_ref(p, lhs_name); + assign_named_ref (p, named_ref_copy (lhs_name)); current_rule = grammar_end; @@ -250,22 +253,25 @@ grammar_current_rule_begin (symbol *lhs, location loc, /*----------------------------------------------------------------------. | A symbol should be used if either: | | 1. It has a destructor. | -| 2. --warnings=midrule-values and the symbol is a mid-rule symbol | -| (i.e., the generated LHS replacing a mid-rule action) that was | -| assigned to or used, as in "exp: { $$ = 1; } { $$ = $1; }". | +| 2. The symbol is a mid-rule symbol (i.e., the generated LHS | +| replacing a mid-rule action) that was assigned to or used, as in | +| "exp: { $$ = 1; } { $$ = $1; }". | `----------------------------------------------------------------------*/ static bool -symbol_should_be_used (symbol_list const *s) +symbol_should_be_used (symbol_list const *s, bool *midrule_warning) { if (symbol_destructor_get (s->content.sym)->code) return true; - if (warnings_flag & warnings_midrule_values) - 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)); + if ((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)) + { + *midrule_warning = true; + return true; + } return false; } @@ -309,17 +315,31 @@ 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 (! (l->action_props.is_value_used - || !symbol_should_be_used (l) - /* The default action, $$ = $1, `uses' both. */ - || (!r->action_props.code && (n == 0 || n == 1)))) - { - if (n) - warn_at (r->location, _("unused value: $%d"), n); - else - warn_at (r->location, _("unset value: $$")); - } + { + bool midrule_warning = false; + if (!l->action_props.is_value_used + && symbol_should_be_used (l, &midrule_warning) + /* The default action, $$ = $1, `uses' both. */ + && (r->action_props.code || (n != 0 && n != 1))) + { + void (*warn_at_ptr)(location, char const*, ...) = + midrule_warning ? midrule_value_at : warn_at; + if (n) + warn_at_ptr (r->location, _("unused value: $%d"), n); + else + warn_at_ptr (r->location, _("unset value: $$")); + } + } } + + /* See comments in grammar_current_rule_prec_set for how POSIX + mandates this complaint. It's only for identifiers, so skip + it for char literals and strings, which are always tokens. */ + if (r->ruleprec + && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"' + && !r->ruleprec->declared && !r->ruleprec->prec) + warn_at (r->location, _("token for %%prec is not defined: %s"), + r->ruleprec->tag); } @@ -396,6 +416,16 @@ grammar_midrule_action (void) void grammar_current_rule_prec_set (symbol *precsym, location loc) { + /* POSIX says that any identifier is a nonterminal if it does not + appear on the LHS of a grammar rule and is not defined by %token + or by one of the directives that assigns precedence to a token. We + ignore this here because the only kind of identifier that POSIX + allows to follow a %prec is a token and because assuming it's a + token now can produce more logical error messages. Nevertheless, + grammar_rule_check does obey what we believe is the real intent of + POSIX here: that an error be reported for any identifier that + appears after %prec but that is not defined separately as a + token. */ symbol_class_set (precsym, token_sym, loc, false); if (current_rule->ruleprec) complain_at (loc, _("only one %s allowed per rule"), "%prec"); @@ -611,7 +641,7 @@ prepare_percent_define_front_end_variables (void) 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"); + muscle_percent_define_default ("lr.default-reductions", "most"); else muscle_percent_define_default ("lr.default-reductions", "accepting"); free (lr_type); @@ -621,7 +651,7 @@ prepare_percent_define_front_end_variables (void) { static char const * const values[] = { "lr.type", "lalr", "ielr", "canonical-lr", NULL, - "lr.default-reductions", "all", "consistent", "accepting", NULL, + "lr.default-reductions", "most", "consistent", "accepting", NULL, NULL }; muscle_percent_define_check_values (values);