mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-21 10: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 ?.? (????-??-??) [?]
|
* 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]
|
* 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,
|
453, 457, 467, 468, 469, 470, 474, 475, 480, 481,
|
||||||
485, 486, 490, 491, 492, 505, 514, 518, 522, 530,
|
485, 486, 490, 491, 492, 505, 514, 518, 522, 530,
|
||||||
531, 535, 548, 549, 561, 565, 569, 577, 579, 584,
|
531, 535, 548, 549, 561, 565, 569, 577, 579, 584,
|
||||||
591, 601, 605, 609, 617, 618, 626, 627, 633, 634,
|
591, 601, 605, 609, 617, 622, 634, 635, 641, 642,
|
||||||
635, 642, 642, 650, 651, 652, 657, 660, 662, 664,
|
643, 650, 650, 658, 659, 660, 665, 668, 670, 672,
|
||||||
666, 668, 670, 672, 674, 676, 681, 682, 691, 715,
|
674, 676, 678, 680, 682, 684, 689, 690, 699, 723,
|
||||||
716, 717, 718, 730, 732, 759, 764, 765, 770, 779,
|
724, 725, 726, 738, 740, 767, 772, 773, 778, 787,
|
||||||
780, 784, 785
|
788, 792, 793
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2410,11 +2410,17 @@ yyreduce:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 84:
|
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;
|
break;
|
||||||
|
|
||||||
case 85:
|
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;
|
break;
|
||||||
|
|
||||||
case 90:
|
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_decls:
|
||||||
symbol_decl.1[syms]
|
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_decl.1:
|
||||||
symbol { $$ = symbol_list_sym_new ($1, @1); }
|
symbol
|
||||||
| symbol_decl.1 symbol { $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
|
{
|
||||||
|
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));
|
assign_named_ref (current_rule, named_ref_copy (lhs_name));
|
||||||
|
|
||||||
/* Mark the rule's lhs as a nonterminal if not already so. */
|
/* Mark the rule's lhs as a nonterminal if not already so. */
|
||||||
if (lhs->content->class == unknown_sym)
|
if (lhs->content->class == unknown_sym || lhs->content->class == pct_type_sym)
|
||||||
{
|
symbol_class_set (lhs, nterm_sym, empty_loc, false);
|
||||||
lhs->content->class = nterm_sym;
|
|
||||||
lhs->content->number = nvars;
|
|
||||||
++nvars;
|
|
||||||
}
|
|
||||||
else if (lhs->content->class == token_sym)
|
else if (lhs->content->class == token_sym)
|
||||||
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
||||||
lhs->tag);
|
lhs->tag);
|
||||||
|
|||||||
32
src/symtab.c
32
src/symtab.c
@@ -33,7 +33,6 @@
|
|||||||
#include "intprops.h"
|
#include "intprops.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
|
|
||||||
|
|
||||||
static struct hash_table *symbol_table = NULL;
|
static struct hash_table *symbol_table = NULL;
|
||||||
static struct hash_table *semantic_type_table = NULL;
|
static struct hash_table *semantic_type_table = NULL;
|
||||||
|
|
||||||
@@ -233,7 +232,14 @@ symbol_print (symbol const *s, FILE *f)
|
|||||||
{
|
{
|
||||||
if (s)
|
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_ATTR_PRINT (type_name);
|
||||||
SYMBOL_CODE_PRINT (destructor);
|
SYMBOL_CODE_PRINT (destructor);
|
||||||
SYMBOL_CODE_PRINT (printer);
|
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. |
|
| 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
|
void
|
||||||
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||||
{
|
{
|
||||||
aver (class != unknown_sym);
|
aver (class != unknown_sym);
|
||||||
sym_content *s = sym->content;
|
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);
|
complain_class_redeclared (sym, class, loc);
|
||||||
else
|
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)
|
if (class == nterm_sym && s->class != nterm_sym)
|
||||||
s->number = nvars++;
|
s->number = nvars++;
|
||||||
else if (class == token_sym && s->number == NUMBER_UNDEFINED)
|
else if (class == token_sym && s->number == NUMBER_UNDEFINED)
|
||||||
@@ -579,7 +603,7 @@ static void
|
|||||||
symbol_check_defined (symbol *sym)
|
symbol_check_defined (symbol *sym)
|
||||||
{
|
{
|
||||||
sym_content *s = sym->content;
|
sym_content *s = sym->content;
|
||||||
if (s->class == unknown_sym)
|
if (s->class == unknown_sym || s->class == pct_type_sym)
|
||||||
{
|
{
|
||||||
complain_symbol_undeclared (sym);
|
complain_symbol_undeclared (sym);
|
||||||
s->class = nterm_sym;
|
s->class = nterm_sym;
|
||||||
|
|||||||
14
src/symtab.h
14
src/symtab.h
@@ -38,9 +38,15 @@
|
|||||||
/** Symbol classes. */
|
/** Symbol classes. */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
unknown_sym, /**< Undefined. */
|
/** Undefined. */
|
||||||
token_sym, /**< Terminal. */
|
unknown_sym,
|
||||||
nterm_sym /**< Nonterminal. */
|
/** 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;
|
} 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.
|
/** Set the \c class associated with \c sym.
|
||||||
|
|
||||||
Whether \c declaring means whether this class definition comes
|
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,
|
void symbol_class_set (symbol *sym, symbol_class class, location loc,
|
||||||
bool declaring);
|
bool declaring);
|
||||||
|
|
||||||
|
|||||||
@@ -195,6 +195,55 @@ input.y:7.4-9: warning: POSIX Yacc does not support %empty [-Wyacc]
|
|||||||
AT_CLEANUP
|
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. ##
|
## Invalid symbol declarations. ##
|
||||||
## ----------------------------- ##
|
## ----------------------------- ##
|
||||||
|
|||||||
Reference in New Issue
Block a user