[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/4] yacc.c, glr.c: check and fix the display of locations
From: |
Akim Demaille |
Subject: |
[PATCH 3/4] yacc.c, glr.c: check and fix the display of locations |
Date: |
Fri, 30 Nov 2012 13:22:11 +0100 |
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.
---
THANKS | 1 +
data/c.m4 | 42 +++++++++++++++++++++++++------
tests/actions.at | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/THANKS b/THANKS
index 8ae024f..218eea7 100644
--- a/THANKS
+++ b/THANKS
@@ -58,6 +58,7 @@ Jim Kent address@hidden
Jim Meyering address@hidden
Joel E. Denny address@hidden
Johan van Selst address@hidden
+Jonathan Fabrizio address@hidden
Jonathan Nieder address@hidden
Juan Manuel Guerrero address@hidden
Kees Zeelenberg address@hidden
diff --git a/data/c.m4 b/data/c.m4
index c2f1a05..dc3d303 100644
--- a/data/c.m4
+++ b/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
diff --git a/tests/actions.at b/tests/actions.at
index f3af0ef..17e6085 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -175,6 +175,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. ##
## ---------------- ##
--
1.8.0.1