tokens: properly define the YYEOF token kind

Currently EOF is handled in an adhoc way, with a #define YYEOF 0 in
the implementation file.  As a result, the user has to define her own
EOF token if she wants to use it, which is a pity.

Give the $end token a visible kind name, YYEOF.  Except that in C,
where enums are not scoped, we would have collisions between all the
definitions of YYEOFs in the header files, so in C, make it
<api.PREFIX>EOF.

* data/skeletons/c.m4 (YYEOF): Override its name to avoid collisions.
Unless the user already gave it a different name.
* data/skeletons/glr.c (YYEOF): Remove.
Use ]b4_symbol(0, [id])[ instead.
Add support for "pre_epilogue", for glr.cc.
* data/skeletons/glr.cc: Remove dead code (never emitted #undefs).
* data/skeletons/yacc.c
* src/parse-gram.c
* src/reader.c
* src/symtab.c
* tests/actions.at
* tests/input.at
This commit is contained in:
Akim Demaille
2020-04-10 18:31:07 +02:00
parent 95421df67b
commit e50de09886
11 changed files with 70 additions and 28 deletions

View File

@@ -537,11 +537,9 @@ m4_define([b4_symbol_map],
# Whether NUM denotes a token that has an exported definition (i.e.,
# shows in enum yytokentype).
m4_define([b4_token_visible_if],
[m4_case(b4_symbol([$1], [tag]),
[$undefined], [$2],
[b4_symbol_if([$1], [is_token],
[b4_symbol_if([$1], [has_id], [$2], [$3])],
[$3])])])
[b4_symbol_if([$1], [is_token],
[b4_symbol_if([$1], [has_id], [$2], [$3])],
[$3])])
# b4_token_has_definition(NUM)

View File

@@ -431,8 +431,11 @@ static const b4_int_type_for([$2]) yy$1[[]] =
## ------------- ##
# Because C enums are not scoped, because tokens are exposed in the
# header, and because these tokens are common to all the parser, we
# header, and because these tokens are common to all the parsers, we
# need to make sure their names don't collide: use the api.prefix.
# YYEOF is special, since the user may give it a different name.
m4_if(b4_symbol(0, id), [YYEOF],
[m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])])
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]])
m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]])

View File

@@ -429,7 +429,6 @@ int yychar;])[
enum { YYENOMEM = -2 };
static const int YYEOF = 0;
static const int YYEMPTY = -2;
typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
@@ -833,9 +832,9 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
#endif // YY_EXCEPTIONS]], [[
*yycharp = ]b4_lex[;]])[
}
if (*yycharp <= YYEOF)
if (*yycharp <= ]b4_symbol(0, [id])[)
{
*yycharp = YYEOF;
*yycharp = ]b4_symbol(0, [id])[;
yytoken = ]b4_symbol_prefix[YYEOF;
YY_DPRINTF ((stderr, "Now at end of input.\n"));
}
@@ -2311,7 +2310,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
{
yysymbol_kind_t yytoken;
int yyj;
if (yychar == YYEOF)
if (yychar == ]b4_symbol(0, [id])[)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
if (yychar != YYEMPTY)
{]b4_locations_if([[
@@ -2724,6 +2723,7 @@ m4_if(b4_prefix, [yy], [],
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])])[
]b4_percent_code_get([[epilogue]])[]dnl
]m4_ifdef([b4_pre_epilogue], [b4_pre_epilogue])[]dnl This is a hack for glr.cc. To remove when we have a better glr.cc.
b4_percent_code_get([[epilogue]])[]dnl
b4_epilogue[]dnl
b4_output_end

View File

@@ -105,6 +105,12 @@ yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_
]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
])[const char* msg);]])[
]b4_percent_define_flag_if([[global_tokens_and_yystype]], [],
[m4_define([b4_pre_epilogue],
[[/* The user is using the C++ token type, not the C one. */
#undef ]b4_symbol(0, [id])
])])[
# Hijack the epilogue to define implementations (yyerror, parser member
# functions etc.).
]m4_append([b4_epilogue],
@@ -329,8 +335,14 @@ b4_percent_code_get([[requires]])[
]dnl Redirections for glr.c.
b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines])
[
[b4_token_defines
])[
]b4_namespace_close[
]dnl Map the name used in c.m4 to the one used in c++.m4.
[#undef ]b4_symbol(0, [id])[
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
#ifndef ]b4_api_PREFIX[STYPE
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
#endif
@@ -338,7 +350,6 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
#endif
]b4_namespace_close[
]m4_define([b4_declare_symbol_enum],
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY

View File

@@ -716,7 +716,6 @@ enum { YYENOMEM = -2 };
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
#define YYEOF 0
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
@@ -1760,9 +1759,9 @@ yyread_pushed_token:]])[
yychar = ]b4_lex[;]])[
}
if (yychar <= YYEOF)
if (yychar <= ]b4_symbol(0, [id])[)
{
yychar = YYEOF;
yychar = ]b4_symbol(0, [id])[;
yytoken = ]b4_symbol_prefix[YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
@@ -1957,10 +1956,10 @@ yyerrlab:
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= YYEOF)
if (yychar <= ]b4_symbol(0, [id])[)
{
/* Return failure if at end of input. */
if (yychar == YYEOF)
if (yychar == ]b4_symbol(0, [id])[)
YYABORT;
}
else