[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFC: propagate the indentation of the actions
From: |
Akim Demaille |
Subject: |
Re: RFC: propagate the indentation of the actions |
Date: |
Tue, 2 Jul 2019 07:40:30 +0200 |
> Le 1 juil. 2019 à 10:21, Paul Eggert <address@hidden> a écrit :
>
> Akim Demaille wrote:
>> Well, we could generate each action twice: once for the good guys,
>> and another for the others. Something like
>
> I wouldn't head down that direction. The C standard says that behavior is
> undefined if a macro argument contains a preprocessing directive like
> '#line'. Sorry, I had forgotten about that rule.
No problem. I wouldn't have anticipated it anyway.
I'm still installing the style patch
(https://lists.gnu.org/archive/html/bison-patches/2019-06/msg00037.html), and
the following patch (which is a cleaned up version of my initial proposal:
https://lists.gnu.org/archive/html/bison-patches/2019-06/msg00012.html).
It is really frustrating that macros bite us again...
We could preserve the splitting patch for D and Java.
commit 18346d38d9f4a264ddb320800afb41144241d94e
Author: Akim Demaille <address@hidden>
Date: Sun Jun 9 09:11:54 2019 +0200
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.
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 <int> '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