muscle: enforce definition syntax for keyword variables

* src/muscle-tab.c (muscle_percent_define_get_kind)
(muscle_percent_define_check_kind): New.
(muscle_percent_define_default): Variables with a default value are
of "keyword" kind.
(muscle_percent_define_flag_if, muscle_percent_define_check_values):
Check that the variable is of keyword kind.
* data/bison.m4: Likewise, but in M4.  That is to say...
(b4_percent_define_default): Define the kind when the variable is undefined.
(b4_percent_define_check_kind): Use a better error message.
(_b4_percent_define_check_values, _b4_percent_define_check_values):
Former "enum" variables should be defined using the keyword syntax.
* doc/bison.texi: Update.
A couple of fixes.
* tests/input.at (%define keyword variables): New.
This commit is contained in:
Akim Demaille
2013-04-14 14:42:15 +02:00
parent 5fad4d4f09
commit c53b684889
4 changed files with 84 additions and 9 deletions

View File

@@ -814,8 +814,8 @@ m4_define([b4_percent_define_flag_if],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_default(VARIABLE, DEFAULT)
# --------------------------------------------
# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword])
# --------------------------------------------------------------
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
# if the %define variable VARIABLE is undefined, set its value to DEFAULT.
# Don't record this as a Bison usage of VARIABLE as there's no reason to
@@ -827,6 +827,8 @@ m4_define([b4_percent_define_flag_if],
m4_define([b4_percent_define_default],
[b4_percent_define_ifdef_([$1], [],
[m4_define([b4_percent_define(]$1[)], [$2])dnl
m4_define([b4_percent_define_kind(]$1[)],
[m4_default([$3], [keyword])])dnl
m4_define([b4_percent_define_loc(]$1[)],
[[[[<skeleton default value>:-1.-1]],
[[<skeleton default value>:-1.-1]]]])dnl
@@ -856,7 +858,7 @@ m4_define([b4_percent_define_check_kind],
b4_percent_define_get_loc([$1]),
[m4_case([$2],
[code], [[%%define variable '%s' requires '{...}' values]],
[keyword], [[%%define variable '%s' requires '...' values]],
[keyword], [[%%define variable '%s' requires keyword values]],
[string], [[%%define variable '%s' requires '"..."' values]])],
[$1])])])dnl
])
@@ -884,7 +886,8 @@ m4_define([b4_percent_define_check_values],
m4_define([_b4_percent_define_check_values],
[b4_percent_define_ifdef_([$1],
[m4_pushdef([b4_good_value], [0])dnl
[b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl
m4_pushdef([b4_good_value], [0])dnl
m4_if($#, 1, [],
[m4_foreach([b4_value], m4_dquote(m4_shift($@)),
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,

View File

@@ -5877,7 +5877,7 @@ Boolean.
@item Default Value:
@code{false}
@item History:
introduced in Bison 2.8
introduced in Bison 3.0
@end itemize
@end deffn
@c api.token.constructor
@@ -6016,7 +6016,7 @@ Use this name as semantic value.
@end itemize
@item History:
introduced in Bison 2.8. Was introduced for Java only in 2.3b as
introduced in Bison 3.0. Was introduced for Java only in 2.3b as
@code{stype}.
@end itemize
@end deffn
@@ -6048,8 +6048,8 @@ feedback will help to stabilize it.)
@item @code{most} otherwise.
@end itemize
@item History:
introduced as @code{lr.default-reduction} in 2.5, renamed as
@code{lr.default-reduction} in 2.8.
introduced as @code{lr.default-reductions} in 2.5, renamed as
@code{lr.default-reduction} in 3.0.
@end itemize
@end deffn
@@ -6066,7 +6066,7 @@ remain in the parser tables. @xref{Unreachable States}.
@item History:
introduced as @code{lr.keep_unreachable_states} in 2.3b, renamed as
@code{lr.keep-unreachable-states} in 2.5, and as
@code{lr.keep-unreachable-state} in 2.8.
@code{lr.keep-unreachable-state} in 3.0.
@end itemize
@end deffn
@c lr.keep-unreachable-state

View File

@@ -579,6 +579,42 @@ muscle_percent_define_get (char const *variable)
return value;
}
/* The kind of VARIABLE. An error if undefined. */
static muscle_kind
muscle_percent_define_get_kind (char const *variable)
{
return muscle_kind_new (muscle_percent_define_get_raw (variable, "kind"));
}
/* Check the kind of VARIABLE. An error if undefined. */
static void
muscle_percent_define_check_kind (char const *variable, muscle_kind kind)
{
if (muscle_percent_define_get_kind (variable) != kind)
{
location loc = muscle_percent_define_get_loc (variable);
switch (kind)
{
case muscle_code:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires '{...}' values",
variable);
break;
case muscle_keyword:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires keyword values",
variable);
break;
case muscle_string:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires '\"...\"' values",
variable);
break;
}
}
}
location
muscle_percent_define_get_loc (char const *variable)
{
@@ -612,6 +648,7 @@ muscle_percent_define_flag_if (char const *variable)
if (muscle_percent_define_ifdef (variable))
{
char *value = muscle_percent_define_get (variable);
muscle_percent_define_check_kind (variable, muscle_keyword);
if (value[0] == '\0' || STREQ (value, "true"))
result = true;
else if (STREQ (value, "false"))
@@ -640,6 +677,7 @@ muscle_percent_define_default (char const *variable, char const *value)
if (!muscle_find_const (name))
{
MUSCLE_INSERT_STRING (name, value);
MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword");
{
uniqstr loc_name = muscle_name (variable, "loc");
location loc;
@@ -661,6 +699,7 @@ muscle_percent_define_check_values (char const * const *values)
char const * const *variablep = values;
uniqstr name = muscle_name (*variablep, NULL);
char *value = string_decode (name);
muscle_percent_define_check_kind (*variablep, muscle_keyword);
if (value)
{
for (++values; *values; ++values)

View File

@@ -1463,6 +1463,39 @@ m4_popdef([AT_TEST])
AT_CLEANUP
## --------------------------- ##
## %define keyword variables. ##
## --------------------------- ##
AT_SETUP([["%define" keyword variables]])
m4_pushdef([AT_TEST],
[AT_DATA([input.y],
[[%define api.pure ]$1[true]$2[
%define api.push-pull ]$1[both]$2[
%define lr.default-reduction ]$1[most]$2[
%define lr.keep-unreachable-state ]$1[true]$2[
%define lr.type ]$1[lalr]$2[
%%
exp: %empty
]])
AT_BISON_CHECK([[input.y]], [0], [],
[[input.y:5.9-15: warning: %define variable 'lr.type' requires keyword values [-Wdeprecated]
input.y:3.9-28: warning: %define variable 'lr.default-reduction' requires keyword values [-Wdeprecated]
input.y:4.9-33: warning: %define variable 'lr.keep-unreachable-state' requires keyword values [-Wdeprecated]
input.y:2.9-21: warning: %define variable 'api.push-pull' requires keyword values [-Wdeprecated]
input.y:1.9-16: warning: %define variable 'api.pure' requires keyword values [-Wdeprecated]
]])
])
AT_TEST(["], ["])
AT_TEST([{], [}])
m4_popdef([AT_TEST])
AT_CLEANUP
## ------------------------ ##
## %define enum variables. ##
## ------------------------ ##