c, c++: also define YYEMPTY in yytoken_kind_t

I have been hesitating a lot before doing it ---after all the user
must not use this kind, so what's the point of showing it in
yytoken_kind_t.  And eventually I chose to play it safe with the
typing system and make it possible to use yytoken_kind_t for all the
tokens, even the "empty token".

* data/skeletons/c.m4: Give an id and a tag to YYEMPTY.
(b4_token_enums): Define YYEMPTY.
* data/skeletons/c++.m4 (b4_token_enums): Define YYEMPTY.
* data/skeletons/glr.c, data/skeletons/glr.cc, data/skeletons/yacc.c:
(YYEMPTY): Remove.
Use b4_symbol(-2, id) instead.
This commit is contained in:
Akim Demaille
2020-04-13 08:05:09 +02:00
parent 5e2e9af56d
commit 64aec0a8d8
5 changed files with 34 additions and 30 deletions

View File

@@ -173,6 +173,7 @@ m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]),
m4_define([b4_token_enums], m4_define([b4_token_enums],
[[enum yytokentype [[enum yytokentype
{ {
]b4_symbol([-2], [id])[ = -2,
]b4_symbol_foreach([b4_token_enum])dnl ]b4_symbol_foreach([b4_token_enum])dnl
[ };]dnl [ };]dnl
]) ])

View File

@@ -434,11 +434,15 @@ static const b4_int_type_for([$2]) yy$1[[]] =
# header, and because these tokens are common to all the parsers, 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. # 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. # YYEOF is special, since the user may give it a different name.
m4_define([b4_symbol(-2, id)], [b4_api_PREFIX[][EMPTY]])
m4_define([b4_symbol(-2, tag)], [[No symbol.]])
m4_if(b4_symbol(0, id), [YYEOF], m4_if(b4_symbol(0, id), [YYEOF],
[m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])]) [m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])])
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]]) m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]])
m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]]) m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]])
# b4_token_define(TOKEN-NUM) # b4_token_define(TOKEN-NUM)
# -------------------------- # --------------------------
# Output the definition of this token as #define. # Output the definition of this token as #define.
@@ -477,6 +481,7 @@ m4_define([b4_token_enums],
# define ]b4_api_PREFIX[TOKENTYPE # define ]b4_api_PREFIX[TOKENTYPE
enum ]b4_api_prefix[tokentype enum ]b4_api_prefix[tokentype
{ {
]b4_symbol([-2], [id])[ = -2,
]b4_symbol_foreach([b4_token_enum])dnl ]b4_symbol_foreach([b4_token_enum])dnl
[ }; [ };
typedef enum ]b4_api_prefix[tokentype ]b4_api_prefix[token_kind_t; typedef enum ]b4_api_prefix[tokentype ]b4_api_prefix[token_kind_t;

View File

@@ -429,8 +429,6 @@ int yychar;])[
enum { YYENOMEM = -2 }; enum { YYENOMEM = -2 };
static const int YYEMPTY = -2;
typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG; typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
#define YYCHK(YYE) \ #define YYCHK(YYE) \
@@ -525,7 +523,7 @@ struct yyGLRStateSet {
/** During nondeterministic operation, yylookaheadNeeds tracks which /** During nondeterministic operation, yylookaheadNeeds tracks which
* stacks have actually needed the current lookahead. During deterministic * stacks have actually needed the current lookahead. During deterministic
* operation, yylookaheadNeeds[0] is not maintained since it would merely * operation, yylookaheadNeeds[0] is not maintained since it would merely
* duplicate yychar != YYEMPTY. */ * duplicate yychar != ]b4_symbol(-2, id)[. */
yybool* yylookaheadNeeds; yybool* yylookaheadNeeds;
ptrdiff_t yysize; ptrdiff_t yysize;
ptrdiff_t yycapacity; ptrdiff_t yycapacity;
@@ -809,7 +807,7 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
{ {
yysymbol_kind_t yytoken; yysymbol_kind_t yytoken;
]b4_parse_param_use()dnl ]b4_parse_param_use()dnl
[ if (*yycharp == YYEMPTY) [ if (*yycharp == ]b4_symbol(-2, id)[)
{ {
YY_DPRINTF ((stderr, "Reading a token\n"));]b4_glr_cc_if([[ YY_DPRINTF ((stderr, "Reading a token\n"));]b4_glr_cc_if([[
#if YY_EXCEPTIONS #if YY_EXCEPTIONS
@@ -887,7 +885,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
# undef YYRECOVERING # undef YYRECOVERING
# define YYRECOVERING() (yystackp->yyerrState != 0) # define YYRECOVERING() (yystackp->yyerrState != 0)
# undef yyclearin # undef yyclearin
# define yyclearin (yychar = YYEMPTY) # define yyclearin (yychar = ]b4_symbol(-2, id)[)
# undef YYFILL # undef YYFILL
# define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal) # define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal)
# undef YYBACKUP # undef YYBACKUP
@@ -1113,7 +1111,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
yynewOption->yyloc = yylloc;])[ yynewOption->yyloc = yylloc;])[
} }
else else
yynewOption->yyrawchar = YYEMPTY; yynewOption->yyrawchar = ]b4_symbol(-2, id)[;
yynewOption->yynext = yystate->yysemantics.yyfirstVal; yynewOption->yynext = yystate->yysemantics.yyfirstVal;
yystate->yysemantics.yyfirstVal = yynewOption; yystate->yysemantics.yyfirstVal = yynewOption;
@@ -2134,7 +2132,7 @@ static yysymbol_kind_t
yypcontext_token (const yyGLRStack *yystackp) yypcontext_token (const yyGLRStack *yystackp)
{ {
YYUSE (yystackp); YYUSE (yystackp);
yysymbol_kind_t yytoken = yychar == YYEMPTY ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar); yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar);
return yytoken; return yytoken;
} }
@@ -2153,7 +2151,7 @@ yypcontext_location (const yyGLRStack *yystackp)
yy_syntax_error_arguments (const yyGLRStack* yystackp, yy_syntax_error_arguments (const yyGLRStack* yystackp,
yysymbol_kind_t yyarg[], int yyargn) yysymbol_kind_t yyarg[], int yyargn)
{ {
yysymbol_kind_t yytoken = yychar == YYEMPTY ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar); yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar);
/* Actual size of YYARG. */ /* Actual size of YYARG. */
int yycount = 0; int yycount = 0;
/* There are many possibilities here to consider: /* There are many possibilities here to consider:
@@ -2313,7 +2311,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
int yyj; int yyj;
if (yychar == ]b4_symbol(0, [id])[) if (yychar == ]b4_symbol(0, [id])[)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
if (yychar != YYEMPTY) if (yychar != ]b4_symbol(-2, id)[)
{]b4_locations_if([[ {]b4_locations_if([[
/* We throw away the lookahead, but the error range /* We throw away the lookahead, but the error range
of the shifted error token must take it into account. */ of the shifted error token must take it into account. */
@@ -2325,7 +2323,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
yytoken = YYTRANSLATE (yychar); yytoken = YYTRANSLATE (yychar);
yydestruct ("Error: discarding", yydestruct ("Error: discarding",
yytoken, &yylval]b4_locuser_args([&yylloc])[); yytoken, &yylval]b4_locuser_args([&yylloc])[);
yychar = YYEMPTY; yychar = ]b4_symbol(-2, id)[;
} }
yytoken = ]b4_yygetToken_call[; yytoken = ]b4_yygetToken_call[;
yyj = yypact[yystackp->yytops.yystates[0]->yylrState]; yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
@@ -2422,7 +2420,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
YY_DPRINTF ((stderr, "Starting parse\n")); YY_DPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; yychar = ]b4_symbol(-2, id)[;
yylval = yyval_default;]b4_locations_if([ yylval = yyval_default;]b4_locations_if([
yylloc = yyloc_default;])[ yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
@@ -2475,7 +2473,7 @@ b4_dollar_popdef])[]dnl
if (yyisShiftAction (yyaction)) if (yyisShiftAction (yyaction))
{ {
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
yychar = YYEMPTY; yychar = ]b4_symbol(-2, id)[;
yyposn += 1; yyposn += 1;
yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[); yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[);
if (0 < yystack.yyerrState) if (0 < yystack.yyerrState)
@@ -2501,7 +2499,7 @@ b4_dollar_popdef])[]dnl
ptrdiff_t yys; ptrdiff_t yys;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1) for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY; yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[;
/* yyprocessOneStack returns one of three things: /* yyprocessOneStack returns one of three things:
@@ -2539,11 +2537,11 @@ b4_dollar_popdef])[]dnl
/* If any yyglrShift call fails, it will fail after shifting. Thus, /* If any yyglrShift call fails, it will fail after shifting. Thus,
a copy of yylval will already be on stack 0 in the event of a a copy of yylval will already be on stack 0 in the event of a
failure in the following loop. Thus, yychar is set to YYEMPTY failure in the following loop. Thus, yychar is set to ]b4_symbol(-2, id)[
before the loop to make sure the user destructor for yylval isn't before the loop to make sure the user destructor for yylval isn't
called twice. */ called twice. */
yytoken_to_shift = YYTRANSLATE (yychar); yytoken_to_shift = YYTRANSLATE (yychar);
yychar = YYEMPTY; yychar = ]b4_symbol(-2, id)[;
yyposn += 1; yyposn += 1;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1) for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
{ {
@@ -2593,7 +2591,7 @@ b4_dollar_popdef])[]dnl
goto yyreturn; goto yyreturn;
yyreturn: yyreturn:
if (yychar != YYEMPTY) if (yychar != ]b4_symbol(-2, id)[)
yydestruct ("Cleanup: discarding lookahead", yydestruct ("Cleanup: discarding lookahead",
YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[); YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[);

View File

@@ -340,7 +340,9 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
]b4_namespace_close[ ]b4_namespace_close[
]dnl Map the name used in c.m4 to the one used in c++.m4. ]dnl Map the name used in c.m4 to the one used in c++.m4.
[#undef ]b4_symbol(0, [id])[ [#undef ]b4_symbol(-2, [id])[
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
#undef ]b4_symbol(0, [id])[
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]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 #ifndef ]b4_api_PREFIX[STYPE

View File

@@ -714,8 +714,7 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
enum { YYENOMEM = -2 }; enum { YYENOMEM = -2 };
#define yyerrok (yyerrstatus = 0) #define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY) #define yyclearin (yychar = ]b4_symbol(-2, id)[)
#define YYEMPTY (-2)
#define YYACCEPT goto yyacceptlab #define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab #define YYABORT goto yyabortlab
@@ -726,7 +725,7 @@ enum { YYENOMEM = -2 };
#define YYBACKUP(Token, Value) \ #define YYBACKUP(Token, Value) \
do \ do \
if (yychar == YYEMPTY) \ if (yychar == ]b4_symbol(-2, id)[) \
{ \ { \
yychar = (Token); \ yychar = (Token); \
yylval = (Value); \ yylval = (Value); \
@@ -1613,7 +1612,7 @@ b4_initialize_parser_state_variables])[
YYDPRINTF ((stderr, "Starting parse\n")); YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */ yychar = ]b4_symbol(-2, id)[; /* Cause a token to be read. */
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [], b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl [b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
@@ -1735,7 +1734,7 @@ yybackup:
/* Not known => get a lookahead token if don't already have one. */ /* Not known => get a lookahead token if don't already have one. */
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
if (yychar == YYEMPTY) if (yychar == ]b4_symbol(-2, id)[)
{]b4_push_if([[ {]b4_push_if([[
if (!yyps->yynew) if (!yyps->yynew)
{]b4_use_push_for_pull_if([], [[ {]b4_use_push_for_pull_if([], [[
@@ -1763,7 +1762,7 @@ yyread_pushed_token:]])[
if (yychar <= ]b4_symbol(0, [id])[) if (yychar <= ]b4_symbol(0, [id])[)
{ {
yychar = ]b4_symbol(0, [id])[; yychar = ]b4_symbol(0, [id])[;
yytoken = ]b4_symbol_prefix[YYEOF; yytoken = ]b4_symbol(0, [kind])[;
YYDPRINTF ((stderr, "Now at end of input.\n")); YYDPRINTF ((stderr, "Now at end of input.\n"));
} }
else else
@@ -1805,7 +1804,7 @@ yyread_pushed_token:]])[
*++yylsp = yylloc;])[ *++yylsp = yylloc;])[
/* Discard the shifted token. */ /* Discard the shifted token. */
yychar = YYEMPTY;]b4_lac_if([[ yychar = ]b4_symbol(-2, id)[;]b4_lac_if([[
YY_LAC_DISCARD ("shift");]])[ YY_LAC_DISCARD ("shift");]])[
goto yynewstate; goto yynewstate;
@@ -1896,8 +1895,7 @@ yyreduce:
yyerrlab: yyerrlab:
/* Make sure we have latest lookahead translation. See comments at /* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */ user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar); yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol_prefix[YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */ /* If not already recovering from an error, report this error. */
if (!yyerrstatus) if (!yyerrstatus)
{ {
@@ -1907,7 +1905,7 @@ yyerrlab:
[[ { [[ {
yypcontext_t yyctx yypcontext_t yyctx
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};]b4_lac_if([[ = {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};]b4_lac_if([[
if (yychar != YYEMPTY) if (yychar != ]b4_symbol(-2, id)[)
YY_LAC_ESTABLISH;]])[ YY_LAC_ESTABLISH;]])[
if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param], if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
[[, ]b4_args(b4_parse_param)])[) == 2) [[, ]b4_args(b4_parse_param)])[) == 2)
@@ -1920,7 +1918,7 @@ yyerrlab:
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[}; = {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};
char const *yymsgp = YY_("syntax error"); char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;]b4_lac_if([[ int yysyntax_error_status;]b4_lac_if([[
if (yychar != YYEMPTY) if (yychar != ]b4_symbol(-2, id)[)
YY_LAC_ESTABLISH;]])[ YY_LAC_ESTABLISH;]])[
yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
if (yysyntax_error_status == 0) if (yysyntax_error_status == 0)
@@ -1967,7 +1965,7 @@ yyerrlab:
{ {
yydestruct ("Error: discarding", yydestruct ("Error: discarding",
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
yychar = YYEMPTY; yychar = ]b4_symbol(-2, id)[;
} }
} }
@@ -2078,7 +2076,7 @@ yyexhaustedlab:
| yyreturn -- parsing is finished, return the result. | | yyreturn -- parsing is finished, return the result. |
`-----------------------------------------------------*/ `-----------------------------------------------------*/
yyreturn: yyreturn:
if (yychar != YYEMPTY) if (yychar != ]b4_symbol(-2, id)[)
{ {
/* Make sure we have latest lookahead translation. See comments at /* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */ user semantic actions for why this is necessary. */