"function declared 'noreturn' should not return") have also been
addressed.
+** New %define variable: api.location.type (glr.cc, lalr1.cc)
+
+ The %define variable api.location.type defines the name of the type to use
+ for locations. When defined, Bison no longer generates the position.hh
+ and location.hh files, nor does the parser will include them: the user is
+ then responsible to define her type.
+
+ This can be used in programs with several parsers to factor their location
+ and position files: let one of them generate them, and let the others
+ simply resue these types and files.
+
+ This feature was actually introduced, but not documented, in Bison 2.5,
+ under the name "location_type" (which is maintained for backward
+ compatibility).
+
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
** Bug fixes
# Don't do that so that we remember whether we're using a user
# request, or the default value.
#
-# b4_percent_define_default([[location_type]], [[location]])
+# b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]])
b4_percent_define_default([[namespace]], m4_defn([b4_prefix]))
[b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
m4_include(b4_pkgdatadir/[c++.m4])
-b4_percent_define_ifdef([[location_type]], [],
+b4_percent_define_ifdef([[api.location.type]], [],
[m4_include(b4_pkgdatadir/[location.cc])])
m4_define([b4_parser_class_name],
# include <string>
# include <iostream>
-]b4_percent_define_ifdef([[location_type]], [],
+]b4_percent_define_ifdef([[api.location.type]], [],
[[# include "location.hh"]])[
]b4_YYDEBUG_define[
typedef ]b4_api_PREFIX[STYPE semantic_type;
# endif
/// Symbol locations.
- typedef ]b4_percent_define_get([[location_type]],
+ typedef ]b4_percent_define_get([[api.location.type]],
[[location]])[ location_type;
/// Tokens.
struct token
b4_percent_define_default([[throws]], [])])
m4_define([b4_throws], [b4_percent_define_get([[throws]])])
-b4_percent_define_default([[location_type]], [Location])])
-m4_define([b4_location_type], [b4_percent_define_get([[location_type]])])
+b4_percent_define_default([[api.location.type]], [Location])])
+m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
b4_percent_define_default([[position_type]], [Position])])
m4_define([b4_position_type], [b4_percent_define_get([[position_type]])])
b4_defines_if([],
[b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
-b4_percent_define_ifdef([[location_type]], [],
+b4_percent_define_ifdef([[api.location.type]], [],
[# Backward compatibility.
m4_define([b4_location_constructors])
m4_include(b4_pkgdatadir/[location.cc])])
#include <string>
#include <iostream>
#include "stack.hh"
-]b4_percent_define_ifdef([[location_type]], [],
+]b4_percent_define_ifdef([[api.location.type]], [],
[[#include "location.hh"]])[
]b4_YYDEBUG_define[
typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif
/// Symbol locations.
- typedef ]b4_percent_define_get([[location_type]],
+ typedef ]b4_percent_define_get([[api.location.type]],
[[location]])[ location_type;
/// Tokens.
struct token
* C++ position:: One point in the source file
* C++ location:: Two points in the source file
+* User Defined Location Type:: Required interface for locations
A Complete C++ Example
Some of the accepted @var{variable}s are:
@itemize @bullet
+@c ================================================== api.location.type
+@item @code{api.location.type}
+@findex %define api.location.type
+
+@itemize @bullet
+@item Language(s): C++
+
+@item Purpose: Define the location type.
+@xref{User Defined Location Type}.
+
+@item Accepted Values: String
+
+@item Default Value: none
+
+@item History: introduced in Bison 2.7
+@end itemize
+
@c ================================================== api.prefix
@item @code{api.prefix}
@findex %define api.prefix
@itemize @bullet
@item Language(s): All
-@item Purpose: Rename exported symbols
+@item Purpose: Rename exported symbols.
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
@item Accepted Values: String
@table @file
@item position.hh
@itemx location.hh
-The definition of the classes @code{position} and @code{location},
-used for location tracking. @xref{C++ Location Values}.
+The definition of the classes @code{position} and @code{location}, used for
+location tracking. These files are not generated if the @code{%define}
+variable @code{api.location.type} is defined. @xref{C++ Location Values}.
@item stack.hh
An auxiliary class @code{stack} used by the parser.
@c - %define filename_type "const symbol::Symbol"
When the directive @code{%locations} is used, the C++ parser supports
-location tracking, see @ref{Tracking Locations}. Two auxiliary classes
-define a @code{position}, a single point in a file, and a @code{location}, a
-range composed of a pair of @code{position}s (possibly spanning several
-files).
+location tracking, see @ref{Tracking Locations}.
+
+By default, two auxiliary classes define a @code{position}, a single point
+in a file, and a @code{location}, a range composed of a pair of
+@code{position}s (possibly spanning several files). But if the
+@code{%define} variable @code{api.location.type} is defined, then these
+classes will not be generated, and the user defined type will be used.
@tindex uint
In this section @code{uint} is an abbreviation for @code{unsigned int}: in
genuine code only the latter is used.
@menu
-* C++ position:: One point in the source file
-* C++ location:: Two points in the source file
+* C++ position:: One point in the source file
+* C++ location:: Two points in the source file
+* User Defined Location Type:: Required interface for locations
@end menu
@node C++ position
@code{filename} defined, or equal filename/line or column.
@end deftypefun
+@node User Defined Location Type
+@subsubsection User Defined Location Type
+@findex %define api.location.type
+
+Instead of using the built-in types you may use the @code{%define} variable
+@code{api.location.type} to specify your own type:
+
+@example
+%define api.location.type @var{LocationType}
+@end example
+
+The requirements over your @var{LocationType} are:
+@itemize
+@item
+it must be copyable;
+
+@item
+in order to compute the (default) value of @code{@@$} in a reduction, the
+parser basically runs
+@example
+@@$.begin = @@$1.begin;
+@@$.end = @@$@var{N}.end; // The location of last right-hand side symbol.
+@end example
+@noindent
+so there must be copyable @code{begin} and @code{end} members;
+
+@item
+alternatively you may redefine the computation of the default location, in
+which case these members are not required (@pxref{Location Default Action});
+
+@item
+if traces are enabled, then there must exist an @samp{std::ostream&
+ operator<< (std::ostream& o, const @var{LocationType}& s)} function.
+@end itemize
+
+@sp 1
+
+In programs with several C++ parsers, you may also use the @code{%define}
+variable @code{api.location.type} to share a common set of built-in
+definitions for @code{position} and @code{location}. For instance, one
+parser @file{master/parser.yy} might use:
+
+@example
+%defines
+%locations
+%define namespace "master::"
+@end example
+
+@noindent
+to generate the @file{master/position.hh} and @file{master/location.hh}
+files, reused by other parsers as follows:
+
+@example
+%define location_type "master::location"
+%code requires @{ #include <master/location.hh> @}
+@end example
+
@node C++ Parser Interface
@subsection C++ Parser Interface
@c - define parser_class_name
const conversion_type conversion[] =
{
{ "api.push_pull", "api.push-pull", },
+ { "location_type", "api.location.type", },
{ "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
};
char const *res = variable;
[AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
AT_CHECK_CALC_LALR1_CC([])
-AT_CHECK_CALC_LALR1_CC([%define location_type Span])
+AT_CHECK_CALC_LALR1_CC([%define api.location.type Span])
AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
[AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
AT_CHECK_CALC_GLR_CC([])
-AT_CHECK_CALC_GLR_CC([%define location_type Span])
+AT_CHECK_CALC_GLR_CC([%define api.location.type Span])
AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
m4_pushdef([AT_LOCATION_IF],
[m4_bmatch([$3], [%locations], [$1], [$2])])
m4_pushdef([AT_LOCATION_TYPE_IF],
-[m4_bmatch([$3], [%define location_type], [$1], [$2])])
+[m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
m4_pushdef([AT_PARAM_IF],
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
m4_pushdef([AT_PURE_IF],