mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
diagnostics: yacc reserves %type to nonterminals
On
%token TOKEN1
%type <ival> TOKEN1 TOKEN2 't'
%token TOKEN2
%%
expr:
bison -Wyacc gives
input.y:2.15-20: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
2 | %type <ival> TOKEN1 TOKEN2 't'
| ^~~~~~
input.y:2.29-31: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
2 | %type <ival> TOKEN1 TOKEN2 't'
| ^~~
input.y:2.22-27: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
2 | %type <ival> TOKEN1 TOKEN2 't'
| ^~~~~~
The messages appear to be out of order, but they are emitted when the
error is found.
* src/symtab.h (symbol_class): Add pct_type_sym, used to denote
symbols appearing in %type.
* src/symtab.c (complain_pct_type_on_token): New.
(symbol_class_set): Check that %type is not applied to tokens.
(symbol_check_defined): pct_type_sym also means undefined.
* src/parse-gram.y (symbol_decl.1): Set the class to pct_type_sym.
* src/reader.c (grammar_current_rule_begin): pct_type_sym also means
undefined.
* tests/input.at (Yacc's %type): New.
This commit is contained in:
24
NEWS
24
NEWS
@@ -2,6 +2,30 @@ GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
|
||||
** New Features
|
||||
|
||||
*** Better POSIX Yacc compatibility diagnostics
|
||||
|
||||
POSIX Yacc restricts %type to nonterminals. This is now diagnosed by
|
||||
-Wyacc.
|
||||
|
||||
%token TOKEN1
|
||||
%type <ival> TOKEN1 TOKEN2 't'
|
||||
%token TOKEN2
|
||||
%%
|
||||
expr:
|
||||
|
||||
gives, with -Wyacc
|
||||
|
||||
input.y:2.15-20: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
2 | %type <ival> TOKEN1 TOKEN2 't'
|
||||
| ^~~~~~
|
||||
input.y:2.29-31: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
2 | %type <ival> TOKEN1 TOKEN2 't'
|
||||
| ^~~
|
||||
input.y:2.22-27: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
2 | %type <ival> TOKEN1 TOKEN2 't'
|
||||
| ^~~~~~
|
||||
|
||||
* Noteworthy changes in release 3.4.90 (2019-10-29) [beta]
|
||||
|
||||
|
||||
@@ -510,11 +510,11 @@ static const yytype_int16 yyrline[] =
|
||||
453, 457, 467, 468, 469, 470, 474, 475, 480, 481,
|
||||
485, 486, 490, 491, 492, 505, 514, 518, 522, 530,
|
||||
531, 535, 548, 549, 561, 565, 569, 577, 579, 584,
|
||||
591, 601, 605, 609, 617, 618, 626, 627, 633, 634,
|
||||
635, 642, 642, 650, 651, 652, 657, 660, 662, 664,
|
||||
666, 668, 670, 672, 674, 676, 681, 682, 691, 715,
|
||||
716, 717, 718, 730, 732, 759, 764, 765, 770, 779,
|
||||
780, 784, 785
|
||||
591, 601, 605, 609, 617, 622, 634, 635, 641, 642,
|
||||
643, 650, 650, 658, 659, 660, 665, 668, 670, 672,
|
||||
674, 676, 678, 680, 682, 684, 689, 690, 699, 723,
|
||||
724, 725, 726, 738, 740, 767, 772, 773, 778, 787,
|
||||
788, 792, 793
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -2410,11 +2410,17 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 84:
|
||||
{ (yyval.yytype_86) = symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0])); }
|
||||
{
|
||||
symbol_class_set ((yyvsp[0].symbol), pct_type_sym, (yylsp[0]), false);
|
||||
(yyval.yytype_86) = symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0]));
|
||||
}
|
||||
break;
|
||||
|
||||
case 85:
|
||||
{ (yyval.yytype_86) = symbol_list_append ((yyvsp[-1].yytype_86), symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0]))); }
|
||||
{
|
||||
symbol_class_set ((yyvsp[0].symbol), pct_type_sym, (yylsp[0]), false);
|
||||
(yyval.yytype_86) = symbol_list_append ((yyvsp[-1].yytype_86), symbol_list_sym_new ((yyvsp[0].symbol), (yylsp[0])));
|
||||
}
|
||||
break;
|
||||
|
||||
case 90:
|
||||
|
||||
@@ -592,11 +592,11 @@ token_decl_for_prec:
|
||||
;
|
||||
|
||||
|
||||
/*-----------------------.
|
||||
| symbol_decls (%type). |
|
||||
`-----------------------*/
|
||||
/*-----------------------------------.
|
||||
| symbol_decls (argument of %type). |
|
||||
`-----------------------------------*/
|
||||
|
||||
// A non empty list of typed symbols.
|
||||
// A non empty list of typed symbols (for %type).
|
||||
symbol_decls:
|
||||
symbol_decl.1[syms]
|
||||
{
|
||||
@@ -612,10 +612,18 @@ symbol_decls:
|
||||
}
|
||||
;
|
||||
|
||||
// One or more token declarations.
|
||||
// One or more token declarations (for %type).
|
||||
symbol_decl.1:
|
||||
symbol { $$ = symbol_list_sym_new ($1, @1); }
|
||||
| symbol_decl.1 symbol { $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
|
||||
symbol
|
||||
{
|
||||
symbol_class_set ($symbol, pct_type_sym, @symbol, false);
|
||||
$$ = symbol_list_sym_new ($symbol, @symbol);
|
||||
}
|
||||
| symbol_decl.1 symbol
|
||||
{
|
||||
symbol_class_set ($symbol, pct_type_sym, @symbol, false);
|
||||
$$ = symbol_list_append ($1, symbol_list_sym_new ($symbol, @symbol));
|
||||
}
|
||||
;
|
||||
|
||||
/*------------------------------------------.
|
||||
|
||||
@@ -232,12 +232,8 @@ grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
assign_named_ref (current_rule, named_ref_copy (lhs_name));
|
||||
|
||||
/* Mark the rule's lhs as a nonterminal if not already so. */
|
||||
if (lhs->content->class == unknown_sym)
|
||||
{
|
||||
lhs->content->class = nterm_sym;
|
||||
lhs->content->number = nvars;
|
||||
++nvars;
|
||||
}
|
||||
if (lhs->content->class == unknown_sym || lhs->content->class == pct_type_sym)
|
||||
symbol_class_set (lhs, nterm_sym, empty_loc, false);
|
||||
else if (lhs->content->class == token_sym)
|
||||
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
||||
lhs->tag);
|
||||
|
||||
32
src/symtab.c
32
src/symtab.c
@@ -33,7 +33,6 @@
|
||||
#include "intprops.h"
|
||||
#include "quote.h"
|
||||
|
||||
|
||||
static struct hash_table *symbol_table = NULL;
|
||||
static struct hash_table *semantic_type_table = NULL;
|
||||
|
||||
@@ -233,7 +232,14 @@ symbol_print (symbol const *s, FILE *f)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
fputs (s->tag, f);
|
||||
symbol_class c = s->content->class;
|
||||
fprintf (f, "%s: %s",
|
||||
c == unknown_sym ? "unknown"
|
||||
: c == pct_type_sym ? "%type"
|
||||
: c == token_sym ? "token"
|
||||
: c == nterm_sym ? "nterm"
|
||||
: NULL, /* abort. */
|
||||
s->tag);
|
||||
SYMBOL_ATTR_PRINT (type_name);
|
||||
SYMBOL_CODE_PRINT (destructor);
|
||||
SYMBOL_CODE_PRINT (printer);
|
||||
@@ -502,15 +508,33 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
|
||||
| Set the CLASS associated with SYM. |
|
||||
`------------------------------------*/
|
||||
|
||||
static void
|
||||
complain_pct_type_on_token (location *loc)
|
||||
{
|
||||
complain (loc, Wyacc,
|
||||
_("POSIX yacc reserves %%type to nonterminals"));
|
||||
}
|
||||
|
||||
void
|
||||
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||
{
|
||||
aver (class != unknown_sym);
|
||||
sym_content *s = sym->content;
|
||||
if (s->class != unknown_sym && s->class != class)
|
||||
if (class == pct_type_sym)
|
||||
{
|
||||
if (s->class == token_sym)
|
||||
complain_pct_type_on_token (&loc);
|
||||
else if (s->class == unknown_sym)
|
||||
s->class = class;
|
||||
}
|
||||
else if (s->class != unknown_sym && s->class != pct_type_sym
|
||||
&& s->class != class)
|
||||
complain_class_redeclared (sym, class, loc);
|
||||
else
|
||||
{
|
||||
if (class == token_sym && s->class == pct_type_sym)
|
||||
complain_pct_type_on_token (&sym->location);
|
||||
|
||||
if (class == nterm_sym && s->class != nterm_sym)
|
||||
s->number = nvars++;
|
||||
else if (class == token_sym && s->number == NUMBER_UNDEFINED)
|
||||
@@ -579,7 +603,7 @@ static void
|
||||
symbol_check_defined (symbol *sym)
|
||||
{
|
||||
sym_content *s = sym->content;
|
||||
if (s->class == unknown_sym)
|
||||
if (s->class == unknown_sym || s->class == pct_type_sym)
|
||||
{
|
||||
complain_symbol_undeclared (sym);
|
||||
s->class = nterm_sym;
|
||||
|
||||
14
src/symtab.h
14
src/symtab.h
@@ -38,9 +38,15 @@
|
||||
/** Symbol classes. */
|
||||
typedef enum
|
||||
{
|
||||
unknown_sym, /**< Undefined. */
|
||||
token_sym, /**< Terminal. */
|
||||
nterm_sym /**< Nonterminal. */
|
||||
/** Undefined. */
|
||||
unknown_sym,
|
||||
/** Declared with %type: same as Undefined, but triggered a Wyacc if
|
||||
applied to a terminal. */
|
||||
pct_type_sym,
|
||||
/** Terminal. */
|
||||
token_sym,
|
||||
/** Nonterminal. */
|
||||
nterm_sym
|
||||
} symbol_class;
|
||||
|
||||
|
||||
@@ -219,7 +225,7 @@ void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc);
|
||||
/** Set the \c class associated with \c sym.
|
||||
|
||||
Whether \c declaring means whether this class definition comes
|
||||
from %nterm or %token. */
|
||||
from %nterm or %token (but not %type, prec/assoc, etc.). */
|
||||
void symbol_class_set (symbol *sym, symbol_class class, location loc,
|
||||
bool declaring);
|
||||
|
||||
|
||||
@@ -195,6 +195,55 @@ input.y:7.4-9: warning: POSIX Yacc does not support %empty [-Wyacc]
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## Yacc's %type. ##
|
||||
## -------------- ##
|
||||
|
||||
AT_SETUP([Yacc's %type])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%token TOKEN1
|
||||
%nterm nterm1
|
||||
%type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
%token TOKEN2
|
||||
%nterm nterm2
|
||||
%%
|
||||
expr: nterm1 nterm2 nterm3
|
||||
nterm1: TOKEN1
|
||||
nterm2: TOKEN2
|
||||
nterm3: "TOKEN3"
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wyacc input.y], [0], [],
|
||||
[[input.y:2.1-6: warning: POSIX Yacc does not support %nterm [-Wyacc]
|
||||
2 | %nterm nterm1
|
||||
| ^~~~~~
|
||||
input.y:3.14-19: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
3 | %type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
| ^~~~~~
|
||||
input.y:3.28-35: warning: POSIX Yacc does not support string literals [-Wyacc]
|
||||
3 | %type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
| ^~~~~~~~
|
||||
input.y:3.28-35: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
3 | %type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
| ^~~~~~~~
|
||||
input.y:3.58-60: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
3 | %type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
| ^~~
|
||||
input.y:5.1-6: warning: POSIX Yacc does not support %nterm [-Wyacc]
|
||||
5 | %nterm nterm2
|
||||
| ^~~~~~
|
||||
input.y:3.21-26: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
|
||||
3 | %type <ival> TOKEN1 TOKEN2 "TOKEN3" nterm1 nterm2 nterm3 '+'
|
||||
| ^~~~~~
|
||||
input.y:10.9-16: warning: POSIX Yacc does not support string literals [-Wyacc]
|
||||
10 | nterm3: "TOKEN3"
|
||||
| ^~~~~~~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ----------------------------- ##
|
||||
## Invalid symbol declarations. ##
|
||||
## ----------------------------- ##
|
||||
|
||||
Reference in New Issue
Block a user