bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

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