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

@@ -27,6 +27,7 @@ synonyms.
- report: for automaton dumps
- %union
- variant
- yacc: POSIX yacc (%yacc)
# Calculator
The grammar features several special directives:

View File

@@ -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]*\),* *], [

View File

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