mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
d: change YYLocation's type from class to struct
This avoids heap allocation and gives minimal costs for the creation and destruction of the YYParser.Symbol struct if the location tracking is active. Suggested by H. S. Teoh. * data/skeletons/lalr1.d: Here. * doc/bison.texi: Document it. * examples/d/calc/calc.y: Adjust. * tests/calc.at: Test it.
This commit is contained in:
committed by
Akim Demaille
parent
10305f3e94
commit
e5854bbddd
@@ -139,11 +139,11 @@ static assert(__traits(compiles, (new string[1])[0]=(new ]b4_location_type[[1])[
|
|||||||
|
|
||||||
private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]], [[
|
private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]], [[
|
||||||
/**
|
/**
|
||||||
* A class defining a pair of positions. Positions, defined by the
|
* A struct defining a pair of positions. Positions, defined by the
|
||||||
* <code>]b4_position_type[</code> class, denote a point in the input.
|
* <code>]b4_position_type[</code> struct, denote a point in the input.
|
||||||
* Locations represent a part of the input through the beginning
|
* Locations represent a part of the input through the beginning
|
||||||
* and ending positions. */
|
* and ending positions. */
|
||||||
public class ]b4_location_type[
|
public struct ]b4_location_type[
|
||||||
{
|
{
|
||||||
/** The first, inclusive, position in the range. */
|
/** The first, inclusive, position in the range. */
|
||||||
public ]b4_position_type[ begin;
|
public ]b4_position_type[ begin;
|
||||||
@@ -159,9 +159,6 @@ public class ]b4_location_type[
|
|||||||
this.begin = this.end = loc;
|
this.begin = this.end = loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this () {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
|
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
|
||||||
* @@param begin The first position included in the range.
|
* @@param begin The first position included in the range.
|
||||||
@@ -173,10 +170,9 @@ public class ]b4_location_type[
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of the location. For this to be correct,
|
* A representation of the location.
|
||||||
* <code>]b4_position_type[</code> should override the <code>toString</code>
|
*/
|
||||||
* method. */
|
public string toString () const {
|
||||||
public override string toString () const {
|
|
||||||
auto end_col = 0 < end.column ? end.column - 1 : 0;
|
auto end_col = 0 < end.column ? end.column - 1 : 0;
|
||||||
auto res = begin.toString ();
|
auto res = begin.toString ();
|
||||||
if (end.filename && begin.filename != end.filename)
|
if (end.filename && begin.filename != end.filename)
|
||||||
@@ -189,7 +185,7 @@ public class ]b4_location_type[
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private immutable bool yy_location_is_class = true;
|
private immutable bool yy_location_is_class = false;
|
||||||
|
|
||||||
]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
|
]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
|
||||||
{
|
{
|
||||||
@@ -438,7 +434,7 @@ b4_symbol_type_define
|
|||||||
/* Error handling. */
|
/* Error handling. */
|
||||||
int yynerrs_ = 0;]b4_locations_if([[
|
int yynerrs_ = 0;]b4_locations_if([[
|
||||||
/// The location where the error started.
|
/// The location where the error started.
|
||||||
]b4_location_type[ yyerrloc = null;
|
]b4_location_type[ yyerrloc;
|
||||||
|
|
||||||
/// ]b4_location_type[ of the lookahead.
|
/// ]b4_location_type[ of the lookahead.
|
||||||
]b4_location_type[ yylloc;
|
]b4_location_type[ yylloc;
|
||||||
|
|||||||
@@ -13844,8 +13844,8 @@ can be used to print the semantic values. This however may change
|
|||||||
@c - class Location
|
@c - class Location
|
||||||
|
|
||||||
When the directive @code{%locations} is used, the D parser supports
|
When the directive @code{%locations} is used, the D parser supports
|
||||||
location tracking, see @ref{Tracking Locations}. The position
|
location tracking, see @ref{Tracking Locations}. The position and
|
||||||
structure and the location class are provided.
|
the location structures are provided.
|
||||||
|
|
||||||
@deftypeivar {YYLocation} {YYPosition} begin
|
@deftypeivar {YYLocation} {YYPosition} begin
|
||||||
@deftypeivarx {YYLocation} {YYPosition} end
|
@deftypeivarx {YYLocation} {YYPosition} end
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input.empty)
|
if (input.empty)
|
||||||
return Calc.Symbol(TokenKind.YYEOF, new YYLocation(startPos, endPos));
|
return Calc.Symbol(TokenKind.YYEOF, YYLocation(startPos, endPos));
|
||||||
|
|
||||||
// Numbers.
|
// Numbers.
|
||||||
if (input.front.isNumber)
|
if (input.front.isNumber)
|
||||||
@@ -143,7 +143,7 @@ if (isInputRange!R && is(ElementType!R : dchar))
|
|||||||
}
|
}
|
||||||
start = end;
|
start = end;
|
||||||
end.column += lenChars;
|
end.column += lenChars;
|
||||||
return Calc.Symbol(TokenKind.NUM, semanticVal_.ival, new YYLocation(startPos, endPos));
|
return Calc.Symbol(TokenKind.NUM, semanticVal_.ival, YYLocation(startPos, endPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Individual characters
|
// Individual characters
|
||||||
@@ -153,17 +153,17 @@ if (isInputRange!R && is(ElementType!R : dchar))
|
|||||||
end.column++;
|
end.column++;
|
||||||
switch (ch)
|
switch (ch)
|
||||||
{
|
{
|
||||||
case '+': return Calc.Symbol(TokenKind.PLUS, new YYLocation(startPos, endPos));
|
case '+': return Calc.Symbol(TokenKind.PLUS, YYLocation(startPos, endPos));
|
||||||
case '-': return Calc.Symbol(TokenKind.MINUS, new YYLocation(startPos, endPos));
|
case '-': return Calc.Symbol(TokenKind.MINUS, YYLocation(startPos, endPos));
|
||||||
case '*': return Calc.Symbol(TokenKind.STAR, new YYLocation(startPos, endPos));
|
case '*': return Calc.Symbol(TokenKind.STAR, YYLocation(startPos, endPos));
|
||||||
case '/': return Calc.Symbol(TokenKind.SLASH, new YYLocation(startPos, endPos));
|
case '/': return Calc.Symbol(TokenKind.SLASH, YYLocation(startPos, endPos));
|
||||||
case '(': return Calc.Symbol(TokenKind.LPAR, new YYLocation(startPos, endPos));
|
case '(': return Calc.Symbol(TokenKind.LPAR, YYLocation(startPos, endPos));
|
||||||
case ')': return Calc.Symbol(TokenKind.RPAR, new YYLocation(startPos, endPos));
|
case ')': return Calc.Symbol(TokenKind.RPAR, YYLocation(startPos, endPos));
|
||||||
case '\n':
|
case '\n':
|
||||||
{
|
{
|
||||||
end.line++;
|
end.line++;
|
||||||
end.column = 1;
|
end.column = 1;
|
||||||
return Calc.Symbol(TokenKind.EOL, new YYLocation(startPos, endPos));
|
return Calc.Symbol(TokenKind.EOL, YYLocation(startPos, endPos));
|
||||||
}
|
}
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -560,7 +560,7 @@ class CalcLexer(R) : Lexer
|
|||||||
]AT_YYERROR_DEFINE[
|
]AT_YYERROR_DEFINE[
|
||||||
|
|
||||||
YYSemanticType semanticVal_;]AT_LOCATION_IF([[
|
YYSemanticType semanticVal_;]AT_LOCATION_IF([[
|
||||||
YYLocation location = new YYLocation;
|
YYLocation location;
|
||||||
|
|
||||||
public final @property YYPosition startPos()
|
public final @property YYPosition startPos()
|
||||||
{
|
{
|
||||||
@@ -606,13 +606,13 @@ class CalcLexer(R) : Lexer
|
|||||||
|
|
||||||
// EOF.
|
// EOF.
|
||||||
if (input.empty)
|
if (input.empty)
|
||||||
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOF]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
|
|
||||||
// Numbers.
|
// Numbers.
|
||||||
if (input.front.isNumber)
|
if (input.front.isNumber)
|
||||||
{
|
{
|
||||||
semanticVal_.ival = parseInt;
|
semanticVal_.ival = parseInt;
|
||||||
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NUM, semanticVal_.ival]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NUM, semanticVal_.ival]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Individual characters
|
// Individual characters
|
||||||
@@ -630,22 +630,22 @@ class CalcLexer(R) : Lexer
|
|||||||
if (c == '#')
|
if (c == '#')
|
||||||
{
|
{
|
||||||
stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'");
|
stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'");
|
||||||
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYerror]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYerror]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '+': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[PLUS]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '+': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[PLUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '-': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[MINUS]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '-': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[MINUS]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '*': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[STAR]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '*': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[STAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '/': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[SLASH]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '/': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[SLASH]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '(': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[LPAR]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '(': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[LPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case ')': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[RPAR]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case ')': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[RPAR]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '\n': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOL]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '\n': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EOL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '=': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EQUAL]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '=': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[EQUAL]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '^': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[POW]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '^': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[POW]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
case '!': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NOT]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
case '!': return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[NOT]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
default: return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYUNDEF]AT_LOCATION_IF([[, new YYLocation(startPos, endPos)]])[);
|
default: return YYParser.Symbol(TokenKind.]AT_TOKEN_PREFIX[YYUNDEF]AT_LOCATION_IF([[, YYLocation(startPos, endPos)]])[);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user