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.
This commit is contained in:
Akim Demaille
2019-04-22 19:24:11 +02:00
parent 971e72514f
commit 9260e5ca4f
7 changed files with 58 additions and 22 deletions

9
NEWS
View File

@@ -86,6 +86,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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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])

View File

@@ -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_"])

View File

@@ -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], $@)])