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:
Akim Demaille
2021-08-05 08:39:24 +02:00
parent dabde7c560
commit 3c5f73fe51
8 changed files with 95 additions and 30 deletions

View File

@@ -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. ##

View File

@@ -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