bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: api.location.type is unsupported for C parsers


From: Akim Demaille
Subject: Re: api.location.type is unsupported for C parsers
Date: Mon, 22 Apr 2019 19:41:35 +0200

Hi Balázs,

> Le 19 avr. 2019 à 06:33, Akim Demaille <address@hidden> a écrit :
> 
> 
>> Le 18 avr. 2019 à 21:06, Scheidler, Balázs <address@hidden> a écrit :
> 
>> Is this something that is worth considering?
> 
> Yes, you are right, it would be a nice addition to the C API.  I'll
> prepare something for 3.4.

What do you think about the following patch?  Could you please give it a try?  
It's also available there:

https://www.lrde.epita.fr/~akim/private/bison/bison-3.3.4-acfb2.tar.gz

Cheers!

commit d22eac7d211c23ae37e8e936905b6a1203d5442f
Author: Akim Demaille <address@hidden>
Date:   Mon Apr 22 19:24:11 2019 +0200

    api.location.type: support it in C
    
    Reported by Balázs Scheidler.
    
    * data/skeletons/c.m4 (b4_location_type_define): Use api.location.type
    if defined.
    * doc/bison.texi: Document it.
    * tests/local.at (AT_C_IF, AT_LANG_CASE): New.
    Support Span in C.
    * tests/calc.at (Span): Convert it to be usable in C and C++.
    Check api.location.type with yacc.c and glr.c.

diff --git a/NEWS b/NEWS
index 8a423fdf..23e3b6f6 100644
--- a/NEWS
+++ b/NEWS
@@ -61,6 +61,15 @@ GNU Bison NEWS
 
     %define api.header.include {<parser/parse.h>}
 
+*** api.location.type is now supported in C (yacc.c, glr.c)
+
+  The %define variable api.location.type defines the name of the type to use
+  for locations.  When defined, Bison no longer defines YYLTYPE.
+
+  This can be used in programs with several parsers to factor their
+  definition of locations: let one of them generate them, and the others
+  just use them.
+
 ** Documentation
 
   A new example in C shows an simple infix calculator with a hand-written
diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4
index 4db36aff..ff769410 100644
--- a/data/skeletons/bison.m4
+++ b/data/skeletons/bison.m4
@@ -1078,10 +1078,10 @@ m4_define_default([b4_location_initial_line],   [1])
 ## Sanity checks.  ##
 ## --------------- ##
 
-# api.location.prefix={...} (Java and C++).
+# api.location.type={...} (C, C++ and Java).
 b4_percent_define_check_kind([api.location.type], [code], [deprecated])
 
-# api.position.prefix={...} (Java).
+# api.position.type={...} (Java).
 b4_percent_define_check_kind([api.position.type], [code], [deprecated])
 
 # api.prefix >< %name-prefix.
diff --git a/data/skeletons/c.m4 b/data/skeletons/c.m4
index d485cb69..5987232d 100644
--- a/data/skeletons/c.m4
+++ b/data/skeletons/c.m4
@@ -730,7 +730,10 @@ typedef ]b4_percent_define_get([[api.value.type]])[ 
]b4_api_PREFIX[STYPE;
 # -----------------------
 m4_define([b4_location_type_define],
 [[/* Location type.  */
-#if ! defined ]b4_api_PREFIX[LTYPE && ! defined 
]b4_api_PREFIX[LTYPE_IS_DECLARED
+]b4_percent_define_ifdef([[api.location.type]],
+[[typedef ]b4_percent_define_get([[api.location.type]])[ ]b4_api_PREFIX[LTYPE;
+]],
+[[#if ! defined ]b4_api_PREFIX[LTYPE && ! defined 
]b4_api_PREFIX[LTYPE_IS_DECLARED
 typedef struct ]b4_api_PREFIX[LTYPE ]b4_api_PREFIX[LTYPE;
 struct ]b4_api_PREFIX[LTYPE
 {
@@ -742,7 +745,7 @@ struct ]b4_api_PREFIX[LTYPE
 # define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
 # define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
 #endif
-]])
+]])])
 
 
 # b4_declare_yylstype
diff --git a/doc/bison.texi b/doc/bison.texi
index 41e75d28..59da4084 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -5975,7 +5975,7 @@ Introduced in Bison 3.2.
 @deffn {Directive} {%define api.location.type} @address@hidden@}
 
 @itemize @bullet
address@hidden Language(s): C++, Java
address@hidden Language(s): C, C++, Java
 
 @item Purpose: Define the location type.
 @xref{User Defined Location Type}.
@@ -5985,8 +5985,7 @@ Introduced in Bison 3.2.
 @item Default Value: none
 
 @item History:
-Introduced in Bison 2.7 for C, C++ and Java.  Introduced under the name
address@hidden for C++ in Bison 2.5 and for Java in Bison 2.4.
+Introduced in Bison 2.7 for C++ and Java, in Bison 3.4 for C.
 @end itemize
 @end deffn
 
diff --git a/tests/calc.at b/tests/calc.at
index 87761c73..38f85dcd 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -289,18 +289,17 @@ AT_DATA_GRAMMAR([calc.y],
 %code requires
 {
 ]AT_LOCATION_TYPE_SPAN_IF([[
-# include <iostream>
-  struct Point
+  typedef struct
   {
     int l;
     int c;
-  };
+  } Point;
 
-  struct Span
+  typedef struct
   {
     Point first;
     Point last;
-  };
+  } Span;
 
 # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
   do                                                                    \
@@ -313,7 +312,13 @@ AT_DATA_GRAMMAR([calc.y],
       {                                                                 \
         (Current).first = (Current).last = YYRHSLOC (Rhs, 0).last;      \
       }                                                                 \
-  while (false)
+  while (0)
+
+]AT_C_IF(
+[[#include <stdio.h>
+void location_print (FILE *o, Span s);
+#define LOCATION_PRINT location_print
+]])[
 
 ]])[
   /* Exercise pre-prologue dependency to %union.  */
@@ -416,7 +421,8 @@ power (int base, int exponent)
   return res;
 }
 
-]AT_LOCATION_TYPE_SPAN_IF([[
+]AT_LOCATION_TYPE_SPAN_IF([AT_CXX_IF([[
+#include <iostream>
 namespace
 {
   std::ostream&
@@ -430,7 +436,17 @@ namespace
     return o;
   }
 }
-]])[
+]], [[
+void
+location_print (FILE *o, Span s)
+{
+  fprintf (o, "%d.%d", s.first.l, s.first.c);
+  if (s.first.l != s.last.l)
+    fprintf (o, "-%d.%d", s.last.l, s.last.c - 1);
+  else if (s.first.c != s.last.c - 1)
+    fprintf (o, "-%d", s.last.c - 1);
+}
+]])])[
 ]AT_YYERROR_DEFINE[
 ]AT_DEFINES_IF([],
 [AT_CALC_LEX
@@ -684,6 +700,7 @@ AT_CHECK_CALC_LALR()
 
 AT_CHECK_CALC_LALR([%defines])
 AT_CHECK_CALC_LALR([%locations])
+AT_CHECK_CALC_LALR([%locations %define api.location.type {Span}])
 
 AT_CHECK_CALC_LALR([%name-prefix "calc"])
 AT_CHECK_CALC_LALR([%verbose])
@@ -726,6 +743,7 @@ AT_CHECK_CALC_GLR()
 
 AT_CHECK_CALC_GLR([%defines])
 AT_CHECK_CALC_GLR([%locations])
+AT_CHECK_CALC_GLR([%locations %define api.location.type {Span}])
 AT_CHECK_CALC_GLR([%name-prefix "calc"])
 AT_CHECK_CALC_GLR([%define api.prefix {calc}])
 AT_CHECK_CALC_GLR([%verbose])
diff --git a/tests/headers.at b/tests/headers.at
index 96ac83e7..8b19d3fe 100644
--- a/tests/headers.at
+++ b/tests/headers.at
@@ -65,7 +65,6 @@ AT_TEST_CPP_GUARD_H([9foo],        [%glr-parser])
 ## export YYLTYPE.  ##
 ## ---------------- ##
 
-
 AT_SETUP([export YYLTYPE])
 
 AT_BISON_OPTION_PUSHDEFS([%name-prefix "my_"])
diff --git a/tests/local.at b/tests/local.at
index ecb0fe04..1f55bedc 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -157,6 +157,8 @@ m4_pushdef([AT_LANG],
             [AT_CXX_IF([c++],
                        [AT_D_IF([d],
                                 [c])])])])
+m4_pushdef([AT_C_IF],
+[m4_if(AT_LANG, [c], [$1], [$2])])
 m4_pushdef([AT_GLR_IF],
 [m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])])
 m4_pushdef([AT_LALR1_CC_IF],
@@ -288,13 +290,12 @@ AT_TOKEN_CTOR_IF(
  m4_pushdef([AT_YYLEX_PRE_ARGS],    [])
 ])])
 
-# Handle the different types of location components.
 
-AT_CXX_IF(
-  [AT_LOCATION_TYPE_SPAN_IF(
+# Handle the different types of location components.
+AT_LOCATION_TYPE_SPAN_IF(
     [AT_LOC_PUSHDEF([first.l], [first.c], [last.l], [last.c])],
-    [AT_LOC_PUSHDEF([begin.line], [begin.column], [end.line], [end.column])])],
-  [AT_LOC_PUSHDEF([first_line], [first_column], [last_line], [last_column])])
+    [AT_CXX_IF([AT_LOC_PUSHDEF([begin.line], [begin.column], [end.line], 
[end.column])],
+               [AT_LOC_PUSHDEF([first_line], [first_column], [last_line], 
[last_column])])])
 
 
 AT_GLR_IF([AT_KEYWORDS([glr])])
@@ -334,6 +335,7 @@ m4_popdef([AT_LEXPARAM_IF])
 m4_popdef([AT_YACC_IF])
 m4_popdef([AT_GLR_IF])
 m4_popdef([AT_CXX_IF])
+m4_popdef([AT_C_IF])
 m4_popdef([AT_LANG])
 m4_popdef([AT_JAVA_IF])
 m4_popdef([AT_GLR_CC_IF])
@@ -349,6 +351,12 @@ AT_LOC_POPDEF])dnl
 ## Generating Grammar Files.  ##
 ## -------------------------- ##
 
+# AT_LANG_CASE(LANG1, IF-LANG1, LANG2, IF-LANG2, ..., DEFAULT)
+# ------------------------------------------------------------
+m4_define([AT_LANG_CASE],
+[m4_case(AT_LANG, $@)])
+
+
 # _AT_LANG_DISPATCH(LANG, MACRO, ARGS)
 # ------------------------------------
 # Call the specialization of MACRO for LANG with ARGS.  Complain if
@@ -990,7 +998,7 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
 
 
 # AT_LANG_FOR_EACH_STD(BODY)
-# -------------------------------
+# --------------------------
 m4_define([AT_LANG_FOR_EACH_STD],  [AT_LANG_DISPATCH([$0], $@)])
 
 




reply via email to

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