mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-10 12:53: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 ?.? (????-??-??) [?]
|
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||||
|
|
||||||
** Bug fixes
|
** 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
|
Cris van Pelt cris@amf03054.office.wxs.nl
|
||||||
Csaba Raduly csaba_22@yahoo.co.uk
|
Csaba Raduly csaba_22@yahoo.co.uk
|
||||||
Dagobert Michelsen dam@baltic-online.de
|
Dagobert Michelsen dam@baltic-online.de
|
||||||
|
Daniel Frużyński daniel@poradnik-webmastera.com
|
||||||
Daniel Hagerty hag@gnu.org
|
Daniel Hagerty hag@gnu.org
|
||||||
David J. MacKenzie djm@gnu.org
|
David J. MacKenzie djm@gnu.org
|
||||||
David Kastrup dak@gnu.org
|
David Kastrup dak@gnu.org
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ m4_define([b4_position_define],
|
|||||||
[[ /// Abstract a position.
|
[[ /// Abstract a position.
|
||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
public:
|
public:]m4_ifdef([b4_location_constructors], [[
|
||||||
]m4_ifdef([b4_location_constructors], [[
|
|
||||||
/// Construct a position.
|
/// Construct a position.
|
||||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||||
unsigned int l = ]b4_location_initial_line[u,
|
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.
|
/// (line related) Advance to the COUNT next lines.
|
||||||
void lines (int count = 1)
|
void lines (int count = 1)
|
||||||
{
|
{
|
||||||
column = ]b4_location_initial_column[u;
|
if (count)
|
||||||
line += 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.
|
/// (column related) Advance to the COUNT next columns.
|
||||||
void columns (int count = 1)
|
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.
|
/// Add and assign a position.
|
||||||
inline position&
|
inline position&
|
||||||
operator+= (position& res, const int width)
|
operator+= (position& res, int width)
|
||||||
{
|
{
|
||||||
res.columns (width);
|
res.columns (width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add two position objects.
|
/// Add two position objects.
|
||||||
inline const position
|
inline position
|
||||||
operator+ (const position& begin, const int width)
|
operator+ (position res, int width)
|
||||||
{
|
{
|
||||||
position res = begin;
|
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add and assign a position.
|
/// Add and assign a position.
|
||||||
inline position&
|
inline position&
|
||||||
operator-= (position& res, const int width)
|
operator-= (position& res, int width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add two position objects.
|
/// Add two position objects.
|
||||||
inline const position
|
inline position
|
||||||
operator- (const position& begin, const int width)
|
operator- (position res, int width)
|
||||||
{
|
{
|
||||||
return begin + -width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||||
/// Compare two position objects.
|
/// Compare two position objects.
|
||||||
@@ -186,13 +193,13 @@ m4_define([b4_location_define],
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next columns.
|
/// Extend the current location to the COUNT next columns.
|
||||||
void columns (unsigned int count = 1)
|
void columns (int count = 1)
|
||||||
{
|
{
|
||||||
end += count;
|
end += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next lines.
|
/// Extend the current location to the COUNT next lines.
|
||||||
void lines (unsigned int count = 1)
|
void lines (int count = 1)
|
||||||
{
|
{
|
||||||
end.lines (count);
|
end.lines (count);
|
||||||
}
|
}
|
||||||
@@ -207,26 +214,35 @@ m4_define([b4_location_define],
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Join two location objects to create a location.
|
/// 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;
|
res.end = end.end;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add two location objects.
|
/// Change end position in place.
|
||||||
inline const location operator+ (const location& begin, unsigned int width)
|
inline location& operator+= (location& res, int width)
|
||||||
{
|
{
|
||||||
location res = begin;
|
|
||||||
res.columns (width);
|
res.columns (width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add and assign a location.
|
/// Change end position.
|
||||||
inline location& operator+= (location& res, unsigned int width)
|
inline location operator+ (location res, int width)
|
||||||
{
|
{
|
||||||
res.columns (width);
|
return res += width;
|
||||||
return res;
|
}
|
||||||
|
|
||||||
|
/// 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]], [[
|
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||||
/// Compare two location objects.
|
/// Compare two location objects.
|
||||||
|
|||||||
@@ -10591,16 +10591,18 @@ filename_type "@var{type}"}.
|
|||||||
The line, starting at 1.
|
The line, starting at 1.
|
||||||
@end deftypeivar
|
@end deftypeivar
|
||||||
|
|
||||||
@deftypemethod {position} {uint} lines (int @var{height} = 1)
|
@deftypemethod {position} {void} lines (int @var{height} = 1)
|
||||||
Advance by @var{height} lines, resetting the column number.
|
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
|
@end deftypemethod
|
||||||
|
|
||||||
@deftypeivar {position} {uint} column
|
@deftypeivar {position} {uint} column
|
||||||
The column, starting at 1.
|
The column, starting at 1.
|
||||||
@end deftypeivar
|
@end deftypeivar
|
||||||
|
|
||||||
@deftypemethod {position} {uint} columns (int @var{width} = 1)
|
@deftypemethod {position} {void} columns (int @var{width} = 1)
|
||||||
Advance by @var{width} columns, without changing the line number.
|
Advance by @var{width} columns, without changing the line number. The
|
||||||
|
resulting column number cannot be less than 1.
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
@deftypemethod {position} {position&} operator+= (int @var{width})
|
@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.
|
The first, inclusive, position of the range, and the first beyond.
|
||||||
@end deftypeivar
|
@end deftypeivar
|
||||||
|
|
||||||
@deftypemethod {location} {uint} columns (int @var{width} = 1)
|
@deftypemethod {location} {void} columns (int @var{width} = 1)
|
||||||
@deftypemethodx {location} {uint} lines (int @var{height} = 1)
|
@deftypemethodx {location} {void} lines (int @var{height} = 1)
|
||||||
Advance the @code{end} position.
|
Forwarded to the @code{end} position.
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
@deftypemethod {location} {location} operator+ (const location& @var{end})
|
@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})
|
||||||
|
@deftypemethodx {location} {location} operator- (int @var{width})
|
||||||
|
@deftypemethodx {location} {location} operator-= (int @var{width})
|
||||||
Various forms of syntactic sugar.
|
Various forms of syntactic sugar.
|
||||||
@end deftypemethod
|
@end deftypemethod
|
||||||
|
|
||||||
|
|||||||
62
tests/c++.at
62
tests/c++.at
@@ -18,6 +18,68 @@
|
|||||||
AT_BANNER([[C++ Features.]])
|
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. ##
|
## C++ Variant-based Symbols. ##
|
||||||
## --------------------------- ##
|
## --------------------------- ##
|
||||||
|
|||||||
Reference in New Issue
Block a user