From 9260e5ca4fa62ff971fc52a2dd64474dd60e5990 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 22 Apr 2019 19:24:11 +0200 Subject: [PATCH] api.location.type: support it in C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- NEWS | 9 +++++++++ data/skeletons/bison.m4 | 4 ++-- data/skeletons/c.m4 | 7 +++++-- doc/bison.texi | 5 ++--- tests/calc.at | 34 ++++++++++++++++++++++++++-------- tests/headers.at | 1 - tests/local.at | 20 ++++++++++++++------ 7 files changed, 58 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 3228a6fd..f9cd2b42 100644 --- a/NEWS +++ b/NEWS @@ -86,6 +86,15 @@ GNU Bison NEWS %define api.header.include {} +*** 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 769e39f4..4f29c837 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -5975,7 +5975,7 @@ Introduced in Bison 3.2. @deffn {Directive} {%define api.location.type} @{@var{type}@} @itemize @bullet -@item Language(s): C++, Java +@item 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 -@code{location_type} 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 - 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 +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 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], $@)])