mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
c++: fix several issues with locations
Reported by Daniel Frużyński. http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html * data/location.cc (position::columns, position::lines): Check for underflow. Fix some weird function signatures. (location): Accept signed integers as arguments where appropriate. Add operator- and operator+=. * doc/bison.texi (C++ position, C++ location): Various fixes and completion. * tests/c++.at (C++ Locations): New tests.
This commit is contained in:
5
NEWS
5
NEWS
@@ -569,6 +569,11 @@ GNU Bison NEWS
|
||||
...
|
||||
}
|
||||
|
||||
*** C++ locations
|
||||
|
||||
There are operator- and operator-= for 'location'. Negative line/column
|
||||
increments can no longer underflow the resulting value.
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
1
THANKS
1
THANKS
@@ -29,6 +29,7 @@ Cris Bailiff c.bailiff+bison@awayweb.com
|
||||
Cris van Pelt cris@amf03054.office.wxs.nl
|
||||
Csaba Raduly csaba_22@yahoo.co.uk
|
||||
Dagobert Michelsen dam@baltic-online.de
|
||||
Daniel Frużyński daniel@poradnik-webmastera.com
|
||||
Daniel Hagerty hag@gnu.org
|
||||
David J. MacKenzie djm@gnu.org
|
||||
David Kastrup dak@gnu.org
|
||||
|
||||
@@ -25,8 +25,7 @@ m4_define([b4_position_define],
|
||||
[[ /// Abstract a position.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
]m4_ifdef([b4_location_constructors], [[
|
||||
public:]m4_ifdef([b4_location_constructors], [[
|
||||
/// Construct a position.
|
||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||
unsigned int l = ]b4_location_initial_line[u,
|
||||
@@ -53,14 +52,23 @@ m4_define([b4_position_define],
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines (int count = 1)
|
||||
{
|
||||
column = ]b4_location_initial_column[u;
|
||||
line += count;
|
||||
if (count)
|
||||
{
|
||||
column = ]b4_location_initial_column[u;
|
||||
line =
|
||||
0 < count || -count < line
|
||||
? line + count
|
||||
: ]b4_location_initial_line[;
|
||||
}
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns (int count = 1)
|
||||
{
|
||||
column = std::max (]b4_location_initial_column[u, column + count);
|
||||
column =
|
||||
0 < count || -count < column
|
||||
? column + count
|
||||
: ]b4_location_initial_column[;
|
||||
}
|
||||
/** \} */
|
||||
|
||||
@@ -74,32 +82,31 @@ m4_define([b4_position_define],
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator+= (position& res, const int width)
|
||||
operator+= (position& res, int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator+ (const position& begin, const int width)
|
||||
inline position
|
||||
operator+ (position res, int width)
|
||||
{
|
||||
position res = begin;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator-= (position& res, const int width)
|
||||
operator-= (position& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator- (const position& begin, const int width)
|
||||
inline position
|
||||
operator- (position res, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
return res -= width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two position objects.
|
||||
@@ -186,13 +193,13 @@ m4_define([b4_location_define],
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns (unsigned int count = 1)
|
||||
void columns (int count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines (unsigned int count = 1)
|
||||
void lines (int count = 1)
|
||||
{
|
||||
end.lines (count);
|
||||
}
|
||||
@@ -207,26 +214,35 @@ m4_define([b4_location_define],
|
||||
};
|
||||
|
||||
/// Join two location objects to create a location.
|
||||
inline const location operator+ (const location& begin, const location& end)
|
||||
inline location operator+ (location res, const location& end)
|
||||
{
|
||||
location res = begin;
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two location objects.
|
||||
inline const location operator+ (const location& begin, unsigned int width)
|
||||
/// Change end position in place.
|
||||
inline location& operator+= (location& res, int width)
|
||||
{
|
||||
location res = begin;
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add and assign a location.
|
||||
inline location& operator+= (location& res, unsigned int width)
|
||||
/// Change end position.
|
||||
inline location operator+ (location res, int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Change end position in place.
|
||||
inline location& operator-= (location& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
inline location operator- (const location& begin, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two location objects.
|
||||
|
||||
@@ -10591,16 +10591,18 @@ filename_type "@var{type}"}.
|
||||
The line, starting at 1.
|
||||
@end deftypeivar
|
||||
|
||||
@deftypemethod {position} {uint} lines (int @var{height} = 1)
|
||||
Advance by @var{height} lines, resetting the column number.
|
||||
@deftypemethod {position} {void} lines (int @var{height} = 1)
|
||||
If @var{height} is not null, advance by @var{height} lines, resetting the
|
||||
column number. The resulting line number cannot be less than 1.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypeivar {position} {uint} column
|
||||
The column, starting at 1.
|
||||
@end deftypeivar
|
||||
|
||||
@deftypemethod {position} {uint} columns (int @var{width} = 1)
|
||||
Advance by @var{width} columns, without changing the line number.
|
||||
@deftypemethod {position} {void} columns (int @var{width} = 1)
|
||||
Advance by @var{width} columns, without changing the line number. The
|
||||
resulting column number cannot be less than 1.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {position} {position&} operator+= (int @var{width})
|
||||
@@ -10642,14 +10644,16 @@ Reset the location to an empty range at the given values.
|
||||
The first, inclusive, position of the range, and the first beyond.
|
||||
@end deftypeivar
|
||||
|
||||
@deftypemethod {location} {uint} columns (int @var{width} = 1)
|
||||
@deftypemethodx {location} {uint} lines (int @var{height} = 1)
|
||||
Advance the @code{end} position.
|
||||
@deftypemethod {location} {void} columns (int @var{width} = 1)
|
||||
@deftypemethodx {location} {void} lines (int @var{height} = 1)
|
||||
Forwarded to the @code{end} position.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {location} {location} operator+ (const location& @var{end})
|
||||
@deftypemethodx {location} {location} operator+ (int @var{width})
|
||||
@deftypemethodx {location} {location} operator+= (int @var{width})
|
||||
@deftypemethodx {location} {location} operator- (int @var{width})
|
||||
@deftypemethodx {location} {location} operator-= (int @var{width})
|
||||
Various forms of syntactic sugar.
|
||||
@end deftypemethod
|
||||
|
||||
|
||||
62
tests/c++.at
62
tests/c++.at
@@ -18,6 +18,68 @@
|
||||
AT_BANNER([[C++ Features.]])
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## C++ Locations. ##
|
||||
## --------------- ##
|
||||
|
||||
AT_SETUP([C++ Locations])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "lalr1.cc"])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%code {#include <sstream>}
|
||||
%locations
|
||||
%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%code
|
||||
{
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: %empty;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
check (const T& in, const std::string& s)
|
||||
{
|
||||
std::stringstream os;
|
||||
os << in;
|
||||
if (os.str () != s)
|
||||
{
|
||||
std::cerr << "fail: " << os.str () << ", expected: " << s << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int fail = 0;
|
||||
]AT_YYLTYPE[ loc; fail += check (loc, "1.1");
|
||||
loc += 10; fail += check (loc, "1.1-10");
|
||||
loc += -5; fail += check (loc, "1.1-5");
|
||||
loc -= 5; fail += check (loc, "1.1");
|
||||
// Check that we don't go below.
|
||||
// http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
|
||||
loc -= 10; fail += check (loc, "1.1");
|
||||
|
||||
loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0");
|
||||
loc.lines (-2); fail += check (loc, "1.1-9.0");
|
||||
loc.lines (-10); fail += check (loc, "1.1");
|
||||
return !fail;
|
||||
}
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input], 0)
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## C++ Variant-based Symbols. ##
|
||||
## --------------------------- ##
|
||||
|
||||
Reference in New Issue
Block a user