From 1161649446ddf96eaf400c38a2217759be41e5bc Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 9 Jun 2019 09:11:54 +0200 Subject: [PATCH] preserve the indentation in the ouput Preserve the actions' initial indentation. For instance, on | %define api.value.type {int} | %% | exp: exp '/' exp { if ($3) | $$ = $1 + $3; | else | $$ = 0; } we used to generate | { if (yyvsp[0]) | yyval = yyvsp[-2] + yyvsp[0]; | else | yyval = 0; } now we produce | { if (yyvsp[0]) | yyval = yyvsp[-2] + yyvsp[0]; | else | yyval = 0; } See https://lists.gnu.org/archive/html/bison-patches/2019-06/msg00012.html. * data/skeletons/bison.m4 (b4_symbol_action): Output the code in column 0, leave indentation matters to the C code. * src/output.c (user_actions_output): Preserve the incoming indentation in the output. (prepare_symbol_definitions): Likewise for %printer/%destructor. * tests/synclines.at (Output columns): New. --- data/skeletons/bison.m4 | 2 +- src/output.c | 26 ++++++++++++----- tests/synclines.at | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4 index ff769410..2c01ac0f 100644 --- a/data/skeletons/bison.m4 +++ b/data/skeletons/bison.m4 @@ -449,7 +449,7 @@ m4_define([b4_symbol_action], [(*yylocationp)])dnl _b4_symbol_case([$1])[]dnl b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl - b4_symbol([$1], [$2]) +b4_symbol([$1], [$2]) b4_syncline([@oline@], [@ofile@])dnl break; diff --git a/src/output.c b/src/output.c index 1f519d0c..85528beb 100644 --- a/src/output.c +++ b/src/output.c @@ -359,9 +359,9 @@ symbol_numbers_output (FILE *out) } -/*---------------------------------. -| Output the user actions to OUT. | -`---------------------------------*/ +/*-------------------------------------------. +| Output the user reduction actions to OUT. | +`-------------------------------------------*/ static void user_actions_output (FILE *out) @@ -370,11 +370,19 @@ user_actions_output (FILE *out) for (rule_number r = 0; r < nrules; ++r) if (rules[r].action) { - fprintf (out, "%s(%d, [b4_syncline(%d, ", + fprintf (out, "%s(%d, [", rules[r].is_predicate ? "b4_predicate_case" : "b4_case", - r + 1, rules[r].action_loc.start.line); - string_output (out, rules[r].action_loc.start.file); - fprintf (out, ")dnl\n[ %s]])\n\n", rules[r].action); + r + 1); + if (!no_lines_flag) + { + fprintf (out, "b4_syncline(%d, ", + rules[r].action_loc.start.line); + string_output (out, rules[r].action_loc.start.file); + fprintf (out, ")dnl\n"); + } + fprintf (out, "[%*s%s]])\n\n", + rules[r].action_loc.start.column - 1, "", + rules[r].action); } fputs ("])\n\n", out); } @@ -482,7 +490,9 @@ prepare_symbol_definitions (void) muscle_location_grow (key, p->location); SET_KEY (pname); - MUSCLE_INSERT_STRING_RAW (key, p->code); + obstack_printf (&muscle_obstack, + "%*s%s", p->location.start.column - 1, "", p->code); + muscle_insert (key, obstack_finish0 (&muscle_obstack)); } } #undef SET_KEY2 diff --git a/tests/synclines.at b/tests/synclines.at index df9d8d66..978d4943 100644 --- a/tests/synclines.at +++ b/tests/synclines.at @@ -497,3 +497,68 @@ AT_CLEANUP m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc]) m4_popdef([AT_TEST]) + + + +## ---------------- ## +## Output columns. ## +## ---------------- ## + +AT_SETUP([Output columns]) + +# This test is fragile: its point is to check the compiler's error +# message, but it seems too hard to do portability (even between +# version of GCC). So instead, let's just check the generated code +# itself. + +AT_BISON_OPTION_PUSHDEFS +AT_DATA([input.y], +[[%{ +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ +%} +%define api.value.type union +%type '0' exp +%destructor { /* --BEGIN */ + destructor + /* --END */ } <*> +%printer { /* --BEGIN */ + printer + /* --END */ } <*> + + + +%left '+' +%% +exp: exp '+' exp { /* --BEGIN */ + $$ = $1 + $3; + @$ = @1 + @3; + /* --END */ } + | '0' +]]) + +AT_BISON_CHECK([-o input.c input.y]) +AT_CHECK([[sed -ne '/--BEGIN/,/--END/{' \ + -e '/input.c/s/ [0-9]* / LINE /;' \ + -e 'p;}' \ + input.c]], 0, +[[ { /* --BEGIN */ + printer + /* --END */ } + { /* --BEGIN */ + printer + /* --END */ } + { /* --BEGIN */ + destructor + /* --END */ } + { /* --BEGIN */ + destructor + /* --END */ } + { /* --BEGIN */ + (yyval.exp) = (yyvsp[-2].exp) + (yyvsp[0].exp); + (yyloc) = (yylsp[-2]) + (yylsp[0]); + /* --END */ } +]]) + +AT_BISON_OPTION_POPDEFS +AT_CLEANUP