From 77bdcc6f0c857d133cea1d9257efe7d8be39de1d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 10 Feb 2020 18:38:42 +0100 Subject: [PATCH] parse.error: document and diagnose the incompatibility with %token-table * doc/bison.texi (Tokens from Literals): Move to code using %token-table to... (Decl Summary: %token-table): here. * data/skeletons/bison.m4: Implement mutual exclusion. * tests/input.at: Check it. * doc/local.mk: Be robust to the removal of doc/. --- data/skeletons/bison.m4 | 8 +++++++ doc/bison.texi | 48 +++++++++++++++++++++-------------------- doc/local.mk | 7 +++--- tests/input.at | 28 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4 index 37a64f1c..ae4154c9 100644 --- a/data/skeletons/bison.m4 +++ b/data/skeletons/bison.m4 @@ -1118,3 +1118,11 @@ b4_percent_define_ifdef([api.value.type], # api.value.union.name. b4_percent_define_check_kind([api.value.union.name], [keyword]) + +# parse.error (custom|detailed) >< token-table. +b4_token_table_if( +[b4_parse_error_bmatch([custom\|detailed], +[b4_complain_at(b4_percent_define_get_loc([parse.error]), + [['%s' and '%s' cannot be used together]], + [%token-table], + [%define parse.error (custom|detailed)])])]) diff --git a/doc/bison.texi b/doc/bison.texi index 37853834..678101a3 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -5780,6 +5780,8 @@ This is similar to how most shells resolve commands. @end deffn @deffn {Directive} %token-table +This feature is obsolescent, avoid it in new projects. + Generate an array of token names in the parser implementation file. The name of the array is @code{yytname}; @code{yytname[@var{i}]} is the name of the token whose internal Bison token code number is @var{i}. The first @@ -5809,6 +5811,29 @@ The number of grammar rules, @item YYNSTATES The number of parser states (@pxref{Parser States}). @end table + +Here's code for looking up a multicharacter token in @code{yytname}, +assuming that the characters of the token are stored in @code{token_buffer}, +and assuming that the token does not contain any characters like @samp{"} +that require escaping. + +@example +for (int i = 0; i < YYNTOKENS; i++) + if (yytname[i] + && yytname[i][0] == '"' + && ! strncmp (yytname[i] + 1, token_buffer, + strlen (token_buffer)) + && yytname[i][strlen (token_buffer) + 1] == '"' + && yytname[i][strlen (token_buffer) + 2] == 0) + break; +@end example + +This method is discouraged: the primary purpose of string aliases is forging +good error messages, not describing the spelling of keywords. In addition, +looking for the token type at runtime incurs a (small but noticeable) cost. + +Finally, @code{%token-table} is incompatible with the @code{custom} and +@code{detailed} values of the @code{parse.error} @code{%define} variable. @end deffn @deffn {Directive} %verbose @@ -7089,29 +7114,6 @@ forging good error messages, not describing the spelling of keywords. In addition, looking for the token type at runtime incurs a (small but noticeable) cost. -The index of the token in the table is the token type's code. The name of a -multicharacter token is recorded in @code{yytname} with a double-quote, the -token's characters, and another double-quote. The token's characters are -escaped as necessary to be suitable as input to Bison. - -Here's code for looking up a multicharacter token in @code{yytname}, -assuming that the characters of the token are stored in @code{token_buffer}, -and assuming that the token does not contain any characters like @samp{"} -that require escaping. - -@example -for (int i = 0; i < YYNTOKENS; i++) - @{ - if (yytname[i] - && yytname[i][0] == '"' - && ! strncmp (yytname[i] + 1, token_buffer, - strlen (token_buffer)) - && yytname[i][strlen (token_buffer) + 1] == '"' - && yytname[i][strlen (token_buffer) + 2] == 0) - break; - @} -@end example - The @code{yytname} table is generated only if you use the @code{%token-table} declaration. @xref{Decl Summary}. @end itemize diff --git a/doc/local.mk b/doc/local.mk index d8c235ed..9695b358 100644 --- a/doc/local.mk +++ b/doc/local.mk @@ -110,14 +110,15 @@ EXTRA_DIST += $(top_srcdir)/doc/bison.help if ! CROSS_COMPILING MAINTAINERCLEANFILES += $(top_srcdir)/doc/bison.help $(top_srcdir)/doc/bison.help: src/bison$(EXEEXT) - $(AM_V_GEN)LC_ALL=C tests/bison --version >doc/bison.help.tmp + $(AM_V_GEN)$(MKDIR_P) %D% + $(AM_V_at) LC_ALL=C tests/bison --version >%D%/bison.help.tmp $(AM_V_at) LC_ALL=C tests/bison --help | \ ## Avoid depending on the path to Bison. sed -e 's,^Usage: .*/bison \[OPTION\],Usage: bison [OPTION],g' \ ## Avoid variations in the output depending on whether we are ## on a glibc system. - -e '/translation bugs/d' >>doc/bison.help.tmp - $(AM_V_at)$(top_srcdir)/build-aux/move-if-change doc/bison.help.tmp $@ + -e '/translation bugs/d' >>%D%/bison.help.tmp + $(AM_V_at)$(top_srcdir)/build-aux/move-if-change %D%/bison.help.tmp $@ endif ! CROSS_COMPILING diff --git a/tests/input.at b/tests/input.at index 5b37d715..29c74e4d 100644 --- a/tests/input.at +++ b/tests/input.at @@ -2888,3 +2888,31 @@ input.y:9.1-21: definition of api.token.raw AT_BISON_OPTION_POPDEFS AT_CLEANUP + + + +## ------------------------------ ## +## %token-table and parse.error. ## +## ------------------------------ ## + +AT_SETUP([[%token-table and parse.error]]) + +# AT_TEST(DIRECTIVES, ERROR-LOCATION) +# ----------------------------------- +m4_pushdef([AT_TEST], +[AT_DATA([[input.y]], +[[$1 +%% +exp: %empty; +]]) +AT_BISON_CHECK([[input.y]], [[1]], [[]], +[$2: error: '%token-table' and '%define parse.error (custom|detailed)' cannot be used together +]) +]) + +AT_TEST([%define parse.error custom %token-table], [[input.y:1.1-26]]) +AT_TEST([%define parse.error detailed %token-table],[[input.y:1.1-28]]) + +m4_popdef([AT_TEST]) + +AT_CLEANUP