Now the traces look more decent: > $ echo '1+2' | YYDEBUG=1 ./_build/g9d/examples/d/calc/calc > Starting parse > Entering state 0 > [...] > Reducing stack by rule 7 (line 63): > $1 = nterm exp (1.1: 1) > $2 = token + (1.2: ) > $3 = nterm exp (1.3: 2) > -> $$ = nterm exp (1.1-3: 3)
I'd like to get some approval before installing it. The test suite is happy. But we need a real test for %printer in D. commit ec584adae379f63f7083166ea797abe0407e8658 Author: Akim Demaille <[email protected]> Date: Wed Jan 6 19:22:18 2021 +0100 d: add support for %printer Currently we display the addresses of the semantic values. Instead, print the values. Add support for YY_USE across languages. * data/skeletons/c.m4, data/skeletons/d.m4 (b4_use): New. * data/skeletons/bison.m4 (b4_symbol_actions): Use b4_use to be portable to D. Add support for %printer, and use it. * data/skeletons/d.m4: Instead of duplicating what's already in c-like.m4, include it. (b4_symbol_action): New. Differs from the one in bison.m4 in that it uses yyval/yyloc instead of *yyvaluep and *yylocationp. * data/skeletons/lalr1.d (yy_symbol_print): Avoid calls to formatting, just call write directly. Use the %printer. * examples/d/calc/calc.y: Specify a printer. Enable traces when $YYDEBUG is set. * tests/calc.at: Fix the use of %printer with D. diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4 index c405b62d..ace9d524 100644 --- a/data/skeletons/bison.m4 +++ b/data/skeletons/bison.m4 @@ -555,7 +555,7 @@ m4_defn([b4_actions_])[]dnl break; }dnl ], -[YY_USE (m4_default([$2], [yykind]));])dnl +[b4_use(m4_default([$2], [yykind]));])dnl m4_popdef([b4_actions_])dnl ]) diff --git a/data/skeletons/c.m4 b/data/skeletons/c.m4 index 1a2eb917..ed2c762c 100644 --- a/data/skeletons/c.m4 +++ b/data/skeletons/c.m4 @@ -163,13 +163,20 @@ m4_popdef([$2])dnl m4_popdef([$1])dnl ])]) + +# b4_use(EXPR) +# ------------ +# Pacify the compiler about some maybe unused value. +m4_define([b4_use], +[YY_USE ($1)]) + # b4_parse_param_use([VAL], [LOC]) # -------------------------------- # 'YY_USE' VAL, LOC if locations are enabled, and all the parse-params. m4_define([b4_parse_param_use], -[m4_ifvaln([$1], [ YY_USE ([$1]);])dnl -b4_locations_if([m4_ifvaln([$2], [ YY_USE ([$2]);])])dnl -b4_parse_param_for([Decl], [Formal], [ YY_USE (Formal); +[m4_ifvaln([$1], [ b4_use([$1]);])dnl +b4_locations_if([m4_ifvaln([$2], [ b4_use([$2]);])])dnl +b4_parse_param_for([Decl], [Formal], [ b4_use(Formal); ])dnl ]) diff --git a/data/skeletons/d.m4 b/data/skeletons/d.m4 index cfb87944..e0a554b9 100644 --- a/data/skeletons/d.m4 +++ b/data/skeletons/d.m4 @@ -18,24 +18,33 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -# _b4_comment(TEXT, OPEN, CONTINUE, END) -# -------------------------------------- -# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines. -# Avoid adding indentation to the first line, as the indentation comes -# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]). -# -# Prefix all the output lines with PREFIX. -m4_define([_b4_comment], -[$2[]m4_bpatsubst(m4_expand([[$1]]), [ -\(.\)], [ -$3\1])$4]) - - -# b4_comment(TEXT, [PREFIX]) -# -------------------------- -# Put TEXT in comment. Prefix all the output lines with PREFIX. -m4_define([b4_comment], -[_b4_comment([$1], [$2/* ], [$2 ], [ */])]) +m4_include(b4_skeletonsdir/[c-like.m4]) + + +# b4_symbol_action(SYMBOL-NUM, ACTION) +# ------------------------------------ +# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM. +m4_define([b4_symbol_action], +[b4_symbol_if([$1], [has_$2], +[b4_dollar_pushdef([yyval], + [$1], + [], + [yyloc])dnl + _b4_symbol_case([$1])[]dnl +b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl +b4_symbol([$1], [$2]) +b4_syncline([@oline@], [@ofile@])dnl + break; + +b4_dollar_popdef[]dnl +])]) + + +# b4_use(EXPR) +# ------------ +# Pacify the compiler about some maybe unused value. +m4_define([b4_use], +[]) # b4_sync_start(LINE, FILE) diff --git a/data/skeletons/lalr1.d b/data/skeletons/lalr1.d index e97613b6..538d6d91 100644 --- a/data/skeletons/lalr1.d +++ b/data/skeletons/lalr1.d @@ -399,20 +399,17 @@ b4_user_union_members `--------------------------------*/ private final void yy_symbol_print (string s, SymbolKind yykind, - ref Value yyvaluep]dnl -b4_locations_if([, ref Location yylocationp])[) + ref Value yyval]b4_locations_if([, ref Location yyloc])[) { if (0 < yydebug) { - string message = s ~ (yykind < yyntokens_ ? " token " : " nterm ") - ~ format("%s", yykind) ~ " ("]b4_locations_if([ - ~ yylocationp.toString() ~ ": "])[; - static if (__traits(compiles, message ~= yyvaluep.toString())) - message ~= yyvaluep.toString(); - else - message ~= format("%s", &yyvaluep); - message ~= ")"; - yycdebugln (message); + File yyo = yyDebugStream; + yyo.write(s); + yyo.write(yykind < yyntokens_ ? " token " : " nterm "); + yyo.write(format("%s", yykind)); + yyo.write(" ("]b4_locations_if([ ~ yyloc.toString() ~ ": "])[); + ]b4_symbol_actions([printer])[ + yyo.write(")\n"); } } ]])[ diff --git a/examples/d/calc/calc.y b/examples/d/calc/calc.y index 572b10b6..765ba382 100644 --- a/examples/d/calc/calc.y +++ b/examples/d/calc/calc.y @@ -21,6 +21,7 @@ %define api.parser.class {Calc} %define parse.error verbose +%define parse.trace %locations @@ -38,6 +39,7 @@ EOL "end of line" %token <ival> NUM "number" %type <ival> exp +%printer { yyo.write($$); } <ival> %left "-" "+" %left "*" "/" @@ -168,6 +170,9 @@ int main() { auto l = calcLexer(stdin); auto p = new Calc(l); + import core.stdc.stdlib : getenv; + if (getenv("YYDEBUG")) + p.setDebugLevel(1); p.parse(); return l.exit_status; } diff --git a/tests/calc.at b/tests/calc.at index 3d319645..77707b89 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -652,7 +652,7 @@ m4_define([_AT_DATA_CALC_Y(d)], { semantic_value ival; }; -%printer { fprintf (yyo, "%d", $$); } <ival>; +%printer { yyo.write($$); } <ival>; %code { ]AT_TOKEN_TRANSLATE_IF([[
