mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
yacc: comply with recent POSIX updates: declare yyerror and yylex
In POSIX Yacc mode, declare yyerror and yylex unless already #defined, or if YYERROR_IS_DECLARED/YYLEX_IS_DECLARED are defined (for consistency with Bison's YYSTYPE_IS_DECLARED/YYLTYPE_IS_DECLARED). See <https://austingroupbugs.net/view.php?id=1388#c5220>. * data/skeletons/c.m4 (b4_function_declare): Resurect. (b4_lex_formals): Since we will possibly expose this prototype in the header, take the prefix into account. * data/skeletons/yacc.c (b4_declare_yyerror_and_yylex): New. (b4_shared_declarations): Use it. * tests/local.at (AT_YACC_IF): New. When in Yacc mode, set the `yacc` Autotest keyword. (AT_YYERROR_DECLARE(c)): Don't declare in Yacc mode, to avoid clashes (since this signature is static). (AT_YYERROR_DEFINE(c)): Don't define as static in Yacc mode. * tests/regression.at (Early token definitions with --yacc): Specify that we are in Yacc mode.
This commit is contained in:
8
NEWS
8
NEWS
@@ -9,6 +9,14 @@ GNU Bison NEWS
|
||||
now generates a *.gv file by default, instead of *.dot. A transition
|
||||
started in Bison 3.4.
|
||||
|
||||
To comply with the latest POSIX standard, in Yacc compatibility mode
|
||||
(options `-y`/`--yacc`) Bison now generates prototypes for yyerror and
|
||||
yylex. In some situations, this is breaking compatibility: if the user
|
||||
has already declared these functions but with some differences (e.g., to
|
||||
declare them as static, or to use specific attributes), the generated
|
||||
parser will fail to compile. To disable these prototypes, #define yyerror
|
||||
(to `yyerror`), and likewise for yylex.
|
||||
|
||||
** Deprecated features
|
||||
|
||||
Support for the YYPRINT macro is removed. It worked only with yacc.c and
|
||||
|
||||
4
TODO
4
TODO
@@ -1,8 +1,4 @@
|
||||
* Soon
|
||||
** POSIX updates
|
||||
See the recent changes about function prototypes in POSIX Yacc. Implement
|
||||
them.
|
||||
|
||||
** scan-code
|
||||
The default case is scanning char-per-char.
|
||||
|
||||
|
||||
@@ -112,8 +112,8 @@ b4_percent_define_default([[api.symbol.prefix]], [[YYSYMBOL_]])
|
||||
# All the yylex formal arguments.
|
||||
# b4_lex_param arrives quoted twice, but we want to keep only one level.
|
||||
m4_define([b4_lex_formals],
|
||||
[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
|
||||
b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
|
||||
[b4_pure_if([[[b4_api_PREFIX[STYPE *yylvalp]], [[&yylval]]][]dnl
|
||||
b4_locations_if([, [b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])])dnl
|
||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
|
||||
|
||||
|
||||
@@ -662,6 +662,14 @@ m4_define([b4_formal],
|
||||
[$1])
|
||||
|
||||
|
||||
# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||
# ------------------------------------------------------------
|
||||
# Declare the function NAME.
|
||||
m4_define([b4_function_declare],
|
||||
[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
|
||||
])
|
||||
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Calling C functions. ##
|
||||
|
||||
@@ -102,6 +102,16 @@ m4_define([b4_yyerror_arg_loc_if],
|
||||
[1], [m4_ifset([b4_parse_param], [$1])],
|
||||
[2], [$1])])])
|
||||
|
||||
# b4_yyerror_formals
|
||||
# ------------------
|
||||
m4_define([b4_yyerror_formals],
|
||||
[b4_pure_if([b4_locations_if([, [[const ]b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])[]dnl
|
||||
m4_ifdef([b4_parse_param], [, b4_parse_param])[]dnl
|
||||
,])dnl
|
||||
[[const char *msg], [msg]]])
|
||||
|
||||
|
||||
|
||||
# b4_yyerror_args
|
||||
# ---------------
|
||||
# Arguments passed to yyerror: user args plus yylloc.
|
||||
@@ -352,17 +362,32 @@ m4_define([b4_declare_yyparse],
|
||||
])
|
||||
|
||||
|
||||
# b4_declare_yyerror_and_yylex
|
||||
# ----------------------------
|
||||
# Comply with POSIX Yacc.
|
||||
# <https://austingroupbugs.net/view.php?id=1388#c5220>
|
||||
m4_define([b4_declare_yyerror_and_yylex],
|
||||
[b4_yacc_if([[#if !defined ]b4_prefix[error && !defined ]b4_api_PREFIX[ERROR_IS_DECLARED
|
||||
]b4_function_declare([b4_prefix[error]], void, b4_yyerror_formals)[
|
||||
#endif
|
||||
#if !defined ]b4_prefix[lex && !defined ]b4_api_PREFIX[LEX_IS_DECLARED
|
||||
]b4_function_declare([b4_prefix[lex]], int, b4_lex_formals)[
|
||||
#endif
|
||||
]])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_shared_declarations
|
||||
# ----------------------
|
||||
# Declaration that might either go into the header (if --header)
|
||||
# or open coded in the parser body.
|
||||
# Declarations that might either go into the header (if --header)
|
||||
# or into the implementation file.
|
||||
m4_define([b4_shared_declarations],
|
||||
[b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||
]b4_declare_yydebug[
|
||||
]b4_percent_code_get([[requires]])[
|
||||
]b4_token_enums_defines[
|
||||
]b4_declare_yylstype[
|
||||
]b4_declare_yyerror_and_yylex[
|
||||
]b4_declare_yyparse[
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
|
||||
|
||||
@@ -6117,11 +6117,13 @@ states and what is done for each type of lookahead token in that state.
|
||||
@end deffn
|
||||
|
||||
@deffn {Directive} %yacc
|
||||
Pretend the option @option{--yacc} was given, i.e., imitate Yacc, including
|
||||
its naming conventions. Only makes sense with the @file{yacc.c}
|
||||
Pretend the option @option{--yacc} was given
|
||||
(@pxref{option-yacc,,@option{--yacc}}), i.e., imitate Yacc, including its
|
||||
naming conventions. Only makes sense with the @file{yacc.c}
|
||||
skeleton. @xref{Tuning the Parser}, for more.
|
||||
|
||||
Of course @code{%yacc} is a Bison extension@dots{}
|
||||
Of course, being a Bison extension, @code{%yacc} is somewhat
|
||||
self-contradictory@dots{}
|
||||
@end deffn
|
||||
|
||||
|
||||
@@ -11832,8 +11834,9 @@ Pretend that @code{%locations} was specified. @xref{Decl Summary}.
|
||||
@item -p @var{prefix}
|
||||
@itemx --name-prefix=@var{prefix}
|
||||
Pretend that @code{%name-prefix "@var{prefix}"} was specified (@pxref{Decl
|
||||
Summary}). Obsoleted by @option{-Dapi.prefix=@var{prefix}}. @xref{Multiple
|
||||
Parsers}.
|
||||
Summary}). The option @option{-p} is specified by POSIX. When POSIX
|
||||
compatibility is not a requirement, @option{-Dapi.prefix=@var{prefix}} is a
|
||||
better option (@pxref{Multiple Parsers}).
|
||||
|
||||
@item -l
|
||||
@itemx --no-lines
|
||||
@@ -11865,26 +11868,46 @@ This is similar to how most shells resolve commands.
|
||||
Pretend that @code{%token-table} was specified. @xref{Decl Summary}.
|
||||
|
||||
@item -y
|
||||
@itemx --yacc
|
||||
Act more like the traditional @command{yacc} command. This can cause
|
||||
different diagnostics to be generated (it implies @option{-Wyacc}), and may
|
||||
change behavior in other minor ways. Most importantly, imitate Yacc's
|
||||
output file name conventions, so that the parser implementation file is
|
||||
called @file{y.tab.c}, and the other outputs are called @file{y.output} and
|
||||
@file{y.tab.h}. Also, generate @code{#define} statements in addition to an
|
||||
@code{enum} to associate token codes with token kind names. Thus, the
|
||||
following shell script can substitute for Yacc, and the Bison distribution
|
||||
contains such a script for compatibility with POSIX:
|
||||
|
||||
@itemx @anchor{option-yacc} --yacc
|
||||
Act more like the traditional @command{yacc} command:
|
||||
@itemize
|
||||
@item
|
||||
Generate different diagnostics (it implies @option{-Wyacc}).
|
||||
@item
|
||||
Generate @code{#define} statements in addition to an @code{enum} to
|
||||
associate token codes with token kind names.
|
||||
@item
|
||||
Generate prototypes for @code{yyerror} and @code{yylex} (since Bison 3.8):
|
||||
@example
|
||||
#! /bin/sh
|
||||
bison -y "$@@"
|
||||
int yylex (void);
|
||||
void yyerror (const char *);
|
||||
@end example
|
||||
As a Bison extension, additional arguments required by @code{%pure-parser},
|
||||
@code{%locations}, @code{%lex-param} and @code{%parse-param} are taken into
|
||||
account. You may disable @code{yyerror}'s prototype with @samp{#define
|
||||
yyerror yyerror} (as specified by POSIX), or with @samp{#define
|
||||
YYERROR_IS_DECLARED} (a Bison extension). Likewise for @code{yylex}.
|
||||
@item
|
||||
Imitate Yacc's output file name conventions, so that the parser
|
||||
implementation file is called @file{y.tab.c}, and the other outputs are
|
||||
called @file{y.output} and @file{y.tab.h}. Do not use @option{--yacc} just
|
||||
to change the output file names since it also triggers all the
|
||||
aforementioned behavior changes; rather use @samp{-o y.tab.c}.
|
||||
@end itemize
|
||||
|
||||
The @option{-y}/@option{--yacc} option is intended for use with traditional
|
||||
Yacc grammars. This option only makes sense for the default C skeleton,
|
||||
@file{yacc.c}. If your grammar uses Bison extensions Bison cannot be
|
||||
Yacc-compatible, even if this option is specified.
|
||||
|
||||
Thus, the following shell script can substitute for Yacc, and the Bison
|
||||
distribution contains such a @command{yacc} script for compatibility with
|
||||
POSIX:
|
||||
|
||||
@example
|
||||
#! /bin/sh
|
||||
bison -y "$@@"
|
||||
@end example
|
||||
@end table
|
||||
|
||||
@node Output Files
|
||||
|
||||
@@ -27,6 +27,7 @@ synonyms.
|
||||
- report: for automaton dumps
|
||||
- %union
|
||||
- variant
|
||||
- yacc: POSIX yacc (%yacc)
|
||||
|
||||
# Calculator
|
||||
The grammar features several special directives:
|
||||
|
||||
@@ -275,6 +275,8 @@ m4_pushdef([AT_MULTISTART_IF],
|
||||
[m4_bmatch([$3], [%start [_a-zA-Z]+ [_a-zA-Z]+], [$1], [$2])])
|
||||
m4_pushdef([AT_PARAM_IF],
|
||||
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
||||
m4_pushdef([AT_YACC_IF],
|
||||
[m4_bmatch([$3], [%yacc], [$1], [$2])])
|
||||
|
||||
# Comma-terminated list of formals parse-parameters.
|
||||
# E.g., %parse-param { int x } %parse-param {int y} -> "int x, int y, ".
|
||||
@@ -427,6 +429,7 @@ AT_LOCATION_TYPE_SPAN_IF(
|
||||
AT_GLR_IF([AT_KEYWORDS([glr])])
|
||||
AT_MULTISTART_IF([AT_KEYWORDS([multistart])])
|
||||
AT_PUSH_IF([AT_KEYWORDS([push])])
|
||||
AT_YACC_IF([AT_KEYWORDS([yacc])])
|
||||
])# _AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
|
||||
@@ -466,6 +469,7 @@ m4_popdef([AT_VALUE_UNION_IF])
|
||||
m4_popdef([AT_PUSH_IF])
|
||||
m4_popdef([AT_PURE_IF])
|
||||
m4_popdef([AT_PARSER_CLASS])
|
||||
m4_popdef([AT_YACC_IF])
|
||||
m4_popdef([AT_PARAM_IF])
|
||||
m4_popdef([AT_MULTISTART_IF])
|
||||
m4_popdef([AT_LEXPARAM_IF])
|
||||
@@ -683,7 +687,7 @@ m4_define([AT_YYERROR_DECLARE_EXTERN(c)],
|
||||
m4_define([AT_YYERROR_DECLARE(c)],
|
||||
[[#include <stdio.h>
|
||||
]AT_LOCATION_PRINT_DECLARE[
|
||||
static ]AT_YYERROR_DECLARE_EXTERN])
|
||||
]AT_YACC_IF([], [[static ]AT_YYERROR_DECLARE_EXTERN])])
|
||||
|
||||
|
||||
# "%define parse.error custom" uses a different format, easy to check.
|
||||
@@ -729,7 +733,7 @@ yyreport_syntax_error (const yypcontext_t *ctx]AT_PARAM_IF([, AT_PARSE_PARAMS])[
|
||||
]])[
|
||||
|
||||
/* A C error reporting function. */
|
||||
static
|
||||
]AT_YACC_IF([], [static])[
|
||||
]AT_YYERROR_PROTOTYPE[
|
||||
{]m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]),
|
||||
[[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\),* *], [
|
||||
|
||||
@@ -87,7 +87,7 @@ AT_SETUP([Early token definitions with --yacc])
|
||||
# Found in GCJ: they expect the tokens to be defined before the user
|
||||
# prologue, so that they can use the token definitions in it.
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_BISON_OPTION_PUSHDEFS([%yacc])
|
||||
|
||||
# Not AT_DATA_GRAMMAR, which uses %code, which is not supported by Yacc.
|
||||
AT_DATA([input.y],
|
||||
@@ -112,7 +112,7 @@ exp: MY_TOKEN;
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([-y -o input.c input.y])
|
||||
AT_BISON_CHECK([--yacc -o input.c input.y])
|
||||
AT_COMPILE([input.o])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
Reference in New Issue
Block a user