mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
yacc.c, glr.c: check and fix the display of locations
In some case, negative column number could be displayed. Make YY_LOCATION_PRINT similar to bison's own implementation of locations. Since the macro is getting fat, make it a static function. Reported by Jonathan Fabrizio. * data/c.m4 (yy_location_print_define): Improve the implementation, and generate the yy_location_print_ function. Adjust YY_LOCATION_PRINT. * tests/actions.at (Location Print): New tests.
This commit is contained in:
1
THANKS
1
THANKS
@@ -58,6 +58,7 @@ Jim Kent jkent@arch.sel.sony.com
|
||||
Jim Meyering jim@meyering.net
|
||||
Joel E. Denny joeldenny@joeldenny.org
|
||||
Johan van Selst johans@stack.nl
|
||||
Jonathan Fabrizio jonathan.fabrizio@lrde.epita.fr
|
||||
Jonathan Nieder jrnieder@gmail.com
|
||||
Juan Manuel Guerrero juan.guerrero@gmx.de
|
||||
Kees Zeelenberg kzlg@users.sourceforge.net
|
||||
|
||||
42
data/c.m4
42
data/c.m4
@@ -655,14 +655,40 @@ m4_define([b4_yy_location_print_define],
|
||||
|
||||
#ifndef YY_LOCATION_PRINT
|
||||
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
|
||||
# define YY_LOCATION_PRINT(File, Loc) \
|
||||
do { \
|
||||
fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column); \
|
||||
if ((Loc).first_line < (Loc).last_line) \
|
||||
fprintf (File, "-%d.%d", (Loc).last_line, (Loc).last_column - 1); \
|
||||
else if ((Loc).first_column < (Loc).last_column - 1) \
|
||||
fprintf (File, "-%d", (Loc).last_column - 1); \
|
||||
} while (0)
|
||||
|
||||
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
|
||||
|
||||
__attribute__((__unused__))
|
||||
]b4_c_function_def([yy_location_print_],
|
||||
[static unsigned],
|
||||
[[FILE *yyo], [yyo]],
|
||||
[[YYLTYPE const * const yylocp], [yylocp]])[
|
||||
{
|
||||
unsigned res = 0;
|
||||
int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
|
||||
if (0 <= yylocp->first_line)
|
||||
{
|
||||
res += fprintf (yyo, "%d", yylocp->first_line);
|
||||
if (0 <= yylocp->first_column)
|
||||
res += fprintf (yyo, ".%d", yylocp->first_column);
|
||||
}
|
||||
if (0 <= yylocp->last_line)
|
||||
{
|
||||
if (yylocp->first_line < yylocp->last_line)
|
||||
{
|
||||
res += fprintf (yyo, "-%d", yylocp->last_line);
|
||||
if (0 <= end_col)
|
||||
res += fprintf (yyo, ".%d", end_col);
|
||||
}
|
||||
else if (0 <= end_col && yylocp->first_column < end_col)
|
||||
res += fprintf (yyo, "-%d", end_col);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
# define YY_LOCATION_PRINT(File, Loc) \
|
||||
yy_location_print_ (File, &(Loc))
|
||||
|
||||
# else
|
||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||
# endif
|
||||
|
||||
@@ -174,6 +174,81 @@ m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Location Print. ##
|
||||
## ---------------- ##
|
||||
|
||||
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
|
||||
# -----------------------------------------------------------------------
|
||||
# Check that the initial location is correct.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([Location print: $1 $2])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%defines /* FIXME: Required by lalr1.cc in Bison 2.6. */
|
||||
%locations
|
||||
%debug
|
||||
%skeleton "$1"
|
||||
]$2[
|
||||
]$3[
|
||||
%code
|
||||
{
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h> // getenv
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp:;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
#define TEST(L1, C1, L2, C2) \
|
||||
]AT_LOC_FIRST_LINE[ = L1; \
|
||||
]AT_LOC_FIRST_COLUMN[ = C1; \
|
||||
]AT_LOC_LAST_LINE[ = L2; \
|
||||
]AT_LOC_LAST_COLUMN[ = C2; \
|
||||
]YY_LOCATION_PRINT(stdout, AT_LOC)[;\
|
||||
putchar ('\n');
|
||||
|
||||
TEST(1, 1, 1, 1);
|
||||
TEST(2, 1, 2, 10);
|
||||
TEST(3, 1, 4, 1);
|
||||
TEST(5, 1, 6, 10);
|
||||
|
||||
TEST(7, 2, 0, 2);
|
||||
TEST(8, 0, 8, 0);
|
||||
}
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input], 0,
|
||||
[[1.1
|
||||
2.1-9
|
||||
3.1-4.0
|
||||
5.1-6.9
|
||||
7.2
|
||||
8.0
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
## FIXME: test Java, and iterate over skeletons.
|
||||
AT_TEST([yacc.c])
|
||||
AT_TEST([glr.c])
|
||||
#AT_TEST([lalr1.cc])
|
||||
#AT_TEST([glr.cc])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Exotic Dollars. ##
|
||||
## ---------------- ##
|
||||
|
||||
Reference in New Issue
Block a user