bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]