Once the Java skeleton taken care of (see https://github.com/akimd/bison/pull/34 and https://lists.gnu.org/r/bison-patches/2020-04/msg00029.html), we will have completed the migration from plain integers to a dignified enum.
Bison 3.6 is getting closer, but of course there remains quite a lot to do, in clean up, tests and doc. Help is most welcome. commit fd98afaf102271f53d0413c596b069e5377754b7 Author: Akim Demaille <[email protected]> Date: Sat Apr 4 10:22:38 2020 +0200 d: use the SymbolType enum for symbol kinds * data/skeletons/d.m4 (b4_symbol_enum, b4_declare_symbol_enum): New. * data/skeletons/lalr1.d: Use them. Use SymbolType, SymbolType.YYSYMBOL_YYEMPTY etc. where appropriate. (undef_token_, token_number_type, yy_error_token_): Remove. diff --git a/data/skeletons/d.m4 b/data/skeletons/d.m4 index 907a3d34..329e960a 100644 --- a/data/skeletons/d.m4 +++ b/data/skeletons/d.m4 @@ -148,9 +148,9 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ = ]) -## ------------------------- ## -## Assigning token numbers. ## -## ------------------------- ## +## -------------------------- ## +## (External) token numbers. ## +## -------------------------- ## # b4_token_enum(TOKEN-NAME, TOKEN-NUMBER) # --------------------------------------- @@ -159,8 +159,8 @@ m4_define([b4_token_enum], [b4_token_format([ %s = %s, ], [$1])]) -# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER) -# ----------------------------------------------------- +# b4_token_enums +# -------------- # Output the definition of the tokens as enums. m4_define([b4_token_enums], [/* Tokens. */ @@ -172,6 +172,39 @@ b4_symbol_foreach([b4_token_enum]) } ]) +## --------------------------- ## +## (Internal) symbol numbers. ## +## --------------------------- ## + + +# b4_symbol_enum(SYMBOL-NUM) +# -------------------------- +# Output the definition of this symbol as an enum. +m4_define([b4_symbol_enum], +[m4_ifval(b4_symbol([$1], [sid]), + [m4_format([[%s = %s]], + b4_symbol([$1], [sid]), + b4_symbol([$1], [number]))])]) + + +# b4_declare_symbol_enum +# ---------------------- +# The definition of the symbol internal numbers as an enum. +# Defining YYEMPTY here is important: it forces the compiler +# to use a signed type, which matters for yytoken. +m4_define([b4_declare_symbol_enum], +[[ /* Symbol type. */ + public enum SymbolType + { + ]m4_join([, + ], + ]b4_symbol_sid([-2])[ = -2, + b4_symbol_map([b4_symbol_enum]))[ + }; +]])]) + + + # b4-case(ID, CODE) # ----------------- m4_define([b4_case], [ case $1: diff --git a/data/skeletons/lalr1.d b/data/skeletons/lalr1.d index 75fd252b..dabaa184 100644 --- a/data/skeletons/lalr1.d +++ b/data/skeletons/lalr1.d @@ -182,11 +182,13 @@ b4_user_union_members };], [m4_if(b4_tag_seen_flag, 0, [[private alias int YYSemanticType;]])])[ -]b4_token_enums(b4_tokens)[ +]b4_token_enums[ ]b4_parser_class_declaration[ { ]b4_identification[ +]b4_declare_symbol_enum[ + ]b4_locations_if([[ private final ]b4_location_type[ yylloc_from_stack (ref YYStack rhs, int n) { @@ -340,7 +342,8 @@ b4_user_union_members } ]b4_parse_trace_if([[ - yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);]])[ + import std.conv : to; + yy_symbol_print ("-> $$ =", to!SymbolType (yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[ yystack.pop (yylen); yylen = 0; @@ -398,7 +401,7 @@ b4_user_union_members | Print this symbol on YYOUTPUT. | `--------------------------------*/ - private final void yy_symbol_print (string s, int yytype, + private final void yy_symbol_print (string s, SymbolType yytype, ref ]b4_yystype[ yyvaluep]dnl b4_locations_if([, ref ]b4_location_type[ yylocationp])[) { @@ -427,7 +430,7 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[) { /// Lookahead and lookahead in internal form. int yychar = yyempty_; - int yytoken = 0; + SymbolType yytoken = SymbolType.YYSYMBOL_YYEMPTY; /* State. */ int yyn = 0; @@ -504,8 +507,7 @@ m4_popdef([b4_at_dollar])])dnl /* Convert token to internal form. */ yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[ - yy_symbol_print ("Next token is", - yytoken, yylval]b4_locations_if([, yylloc])[);]])[ + yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[ /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ @@ -527,8 +529,7 @@ m4_popdef([b4_at_dollar])])dnl else { /* Shift the lookahead token. */]b4_parse_trace_if([[ - yy_symbol_print ("Shifting", yytoken, - yylval]b4_locations_if([, yylloc])[);]])[ + yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[ /* Discard the token being shifted. */ yychar = yyempty_; @@ -564,16 +565,16 @@ m4_popdef([b4_at_dollar])])dnl yystate = yystack.stateAt (0); break; - /*------------------------------------. - | yyerrlab -- here on detecting error | - `------------------------------------*/ + /*--------------------------------------. + | yyerrlab -- here on detecting error. | + `--------------------------------------*/ case YYERRLAB: /* If not already recovering from an error, report this error. */ if (yyerrstatus_ == 0) { ++yynerrs_; if (yychar == yyempty_) - yytoken = yyempty_; + yytoken = SymbolType.YYSYMBOL_YYEMPTY; yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken)); } @@ -622,8 +623,8 @@ m4_popdef([b4_at_dollar])])dnl yyn = yypact_[yystate]; if (!yy_pact_value_is_default_ (yyn)) { - yyn += yy_error_token_; - if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_) + yyn += SymbolType.YYSYMBOL_YYERROR; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolType.YYSYMBOL_YYERROR) { yyn = yytable_[yyn]; if (0 < yyn) @@ -650,9 +651,8 @@ m4_popdef([b4_at_dollar])])dnl yystack.pop (2);])[ /* Shift the error token. */]b4_parse_trace_if([[ - yy_symbol_print ("Shifting", yystos_[yyn], - yylval]b4_locations_if([, yyloc])[);]])[ - + import std.conv : to; + yy_symbol_print ("Shifting", to!SymbolType (yystos_[yyn]), yylval]b4_locations_if([, yyloc])[);]])[ yystate = yyn; yystack.push (yyn, yylval]b4_locations_if([, yyloc])[); label = YYNEWSTATE; @@ -678,7 +678,7 @@ m4_popdef([b4_at_dollar])])dnl } // Generate an error message. - private final string yysyntax_error (int yystate, int tok) + private final string yysyntax_error (int yystate, SymbolType tok) {]b4_parse_error_case([verbose], [[ /* There are many possibilities here to consider: - Assume YYFAIL is not used. It's too flawed to consider. @@ -711,7 +711,7 @@ m4_popdef([b4_at_dollar])])dnl will still contain any token that will not be accepted due to an error action in a later state. */ - if (tok != yyempty_) + if (tok != SymbolType.YYSYMBOL_YYEMPTY) { // FIXME: This method of building the message is not compatible // with internationalization. @@ -730,14 +730,14 @@ m4_popdef([b4_at_dollar])])dnl int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; int count = 0; for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yy_error_token_ + if (yycheck_[x + yyn] == x && x != SymbolType.YYSYMBOL_YYERROR && !yy_table_value_is_error_ (yytable_[x + yyn])) ++count; if (count < 5) { count = 0; for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yy_error_token_ + if (yycheck_[x + yyn] == x && x != SymbolType.YYSYMBOL_YYERROR && !yy_table_value_is_error_ (yytable_[x + yyn])) { res ~= count++ == 0 ? ", expecting " : " or "; @@ -806,40 +806,39 @@ m4_popdef([b4_at_dollar])])dnl yyrule - 1, yylno)); /* The symbols being reduced. */ + import std.conv : to; for (int yyi = 0; yyi < yynrhs; yyi++) yy_symbol_print (format(" $%d =", yyi + 1), - yystos_[yystack.stateAt(yynrhs - (yyi + 1))], + to!SymbolType (yystos_[yystack.stateAt(yynrhs - (yyi + 1))]), ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, b4_rhs_location(yynrhs, yyi + 1)])[); } ]])[ - private static token_number_type yytranslate_ (int t) + private static SymbolType yytranslate_ (int t) { ]b4_api_token_raw_if( [[ import std.conv : to; - return to!byte (t);]], + return to!SymbolType (t);]], [[ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ - immutable token_number_type[] translate_table = + immutable ]b4_int_type_for([b4_translate])[[] translate_table = @{ ]b4_translate[ @}; immutable int user_token_number_max_ = ]b4_user_token_number_max[; - immutable token_number_type undef_token_ = ]b4_undef_token_number[; if (t <= 0) - return YYTokenType.EOF; + return SymbolType.YYSYMBOL_YYEOF; else if (t <= user_token_number_max_) - return translate_table[t]; + { + import std.conv : to; + return to!SymbolType (translate_table[t]); + } else - return undef_token_;]])[ + return SymbolType.YYSYMBOL_YYUNDEF;]])[ } - alias ]b4_int_type_for([b4_translate])[ token_number_type; - - private static immutable token_number_type yy_error_token_ = 1; - private static immutable int yylast_ = ]b4_last[; private static immutable int yynnts_ = ]b4_nterms_number[; private static immutable int yyempty_ = -2;
