mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 17:53:02 +00:00
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.
This commit is contained in:
@@ -449,7 +449,7 @@ m4_define([b4_symbol_action],
|
|||||||
[(*yylocationp)])dnl
|
[(*yylocationp)])dnl
|
||||||
_b4_symbol_case([$1])[]dnl
|
_b4_symbol_case([$1])[]dnl
|
||||||
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])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
|
b4_syncline([@oline@], [@ofile@])dnl
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
26
src/output.c
26
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
|
static void
|
||||||
user_actions_output (FILE *out)
|
user_actions_output (FILE *out)
|
||||||
@@ -370,11 +370,19 @@ user_actions_output (FILE *out)
|
|||||||
for (rule_number r = 0; r < nrules; ++r)
|
for (rule_number r = 0; r < nrules; ++r)
|
||||||
if (rules[r].action)
|
if (rules[r].action)
|
||||||
{
|
{
|
||||||
fprintf (out, "%s(%d, [b4_syncline(%d, ",
|
fprintf (out, "%s(%d, [",
|
||||||
rules[r].is_predicate ? "b4_predicate_case" : "b4_case",
|
rules[r].is_predicate ? "b4_predicate_case" : "b4_case",
|
||||||
r + 1, rules[r].action_loc.start.line);
|
r + 1);
|
||||||
string_output (out, rules[r].action_loc.start.file);
|
if (!no_lines_flag)
|
||||||
fprintf (out, ")dnl\n[ %s]])\n\n", rules[r].action);
|
{
|
||||||
|
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);
|
fputs ("])\n\n", out);
|
||||||
}
|
}
|
||||||
@@ -482,7 +490,9 @@ prepare_symbol_definitions (void)
|
|||||||
muscle_location_grow (key, p->location);
|
muscle_location_grow (key, p->location);
|
||||||
|
|
||||||
SET_KEY (pname);
|
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
|
#undef SET_KEY2
|
||||||
|
|||||||
@@ -497,3 +497,68 @@ AT_CLEANUP
|
|||||||
m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
|
m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
|
||||||
|
|
||||||
m4_popdef([AT_TEST])
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user