[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
diagnostics: yacc reserves %type to nonterminals
From: |
Akim Demaille |
Subject: |
diagnostics: yacc reserves %type to nonterminals |
Date: |
Sun, 17 Nov 2019 09:48:42 +0100 |
commit 28d1ca8f48f7dff1550e6607f7aac33714a664b8
Author: Akim Demaille <address@hidden>
Date: Sat Nov 16 17:26:51 2019 +0100
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.
diff --git a/NEWS b/NEWS
index 8e6aed95..742ea743 100644
--- a/NEWS
+++ b/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]
diff --git a/src/parse-gram.c b/src/parse-gram.c
index 18419525..493ed525 100644
--- a/src/parse-gram.c
+++ b/src/parse-gram.c
@@ -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:
diff --git a/src/parse-gram.y b/src/parse-gram.y
index ccc3c315..0d1cc3f9 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -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));
+ }
;
/*------------------------------------------.
diff --git a/src/reader.c b/src/reader.c
index cf481fd8..fc6a27e6 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -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);
diff --git a/src/symtab.c b/src/symtab.c
index 1b43ef96..73111b51 100644
--- a/src/symtab.c
+++ b/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;
diff --git a/src/symtab.h b/src/symtab.h
index b6e18e61..729f1fb9 100644
--- a/src/symtab.h
+++ b/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);
diff --git a/tests/input.at b/tests/input.at
index fe03f2e1..00e3a508 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -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. ##
## ----------------------------- ##
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- diagnostics: yacc reserves %type to nonterminals,
Akim Demaille <=