mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 00:33:03 +00:00
d: track locations
* configure.ac (DCFLAGS): Pass -g. * data/skeletons/d.m4 (b4_locations_if): Remove, let bison.m4's one do its job. * data/skeletons/lalr1.d (position): Leave filename empty by default. (position::toString): Don't print empty file names. (location::this): New ctor. (location::toString): Match the implementations of C/C++. (yy_semantic_null): Leave undefined, the previous implementation does not compile. * tests/calc.at: Improve the implementation for D. Enable more checks, in particular using locations. * tests/local.at (AT_YYERROR_DEFINE(d)): Fix its implementation.
This commit is contained in:
@@ -192,7 +192,7 @@ BISON_CXX_COMPILER_POSIXLY_CORRECT
|
|||||||
|
|
||||||
# D.
|
# D.
|
||||||
AC_CHECK_PROGS([DC], [dmd])
|
AC_CHECK_PROGS([DC], [dmd])
|
||||||
AC_CHECK_PROGS([DCFLAGS], [])
|
AC_CHECK_PROGS([DCFLAGS], [-g])
|
||||||
AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x])
|
AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x])
|
||||||
|
|
||||||
# Java.
|
# Java.
|
||||||
|
|||||||
@@ -100,12 +100,6 @@ m4_define([b4_location_type_if],
|
|||||||
[b4_percent_define_ifdef([[location_type]], [$1], [$2])])
|
[b4_percent_define_ifdef([[location_type]], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
# b4_locations_if(TRUE, FALSE)
|
|
||||||
# ----------------------------
|
|
||||||
m4_define([b4_locations_if],
|
|
||||||
[m4_if(b4_locations_flag, 1, [$1], [$2])])
|
|
||||||
|
|
||||||
|
|
||||||
# b4_identification
|
# b4_identification
|
||||||
# -----------------
|
# -----------------
|
||||||
m4_define([b4_identification],
|
m4_define([b4_identification],
|
||||||
|
|||||||
@@ -97,12 +97,15 @@ public struct ]b4_position_type[ {
|
|||||||
/** The line number within an input file. */
|
/** The line number within an input file. */
|
||||||
public int line = 1;
|
public int line = 1;
|
||||||
/** The name of the input file. */
|
/** The name of the input file. */
|
||||||
public string filename = "(unspecified file)";
|
public string filename = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A string representation of the position. */
|
* A string representation of the position. */
|
||||||
public string toString() const {
|
public string toString() const {
|
||||||
return format("%s:%d.%d", filename, line, column);
|
if (filename)
|
||||||
|
return format("%s:%d.%d", filename, line, column);
|
||||||
|
else
|
||||||
|
return format("%d.%d", line, column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]])b4_location_type_if([[
|
]])b4_location_type_if([[
|
||||||
@@ -141,6 +144,9 @@ 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.
|
||||||
@@ -156,10 +162,15 @@ public class ]b4_location_type[
|
|||||||
* <code>]b4_position_type[</code> should override the <code>toString</code>
|
* <code>]b4_position_type[</code> should override the <code>toString</code>
|
||||||
* method. */
|
* method. */
|
||||||
public override string toString () const {
|
public override string toString () const {
|
||||||
if (begin == end)
|
auto end_col = 0 < end.column ? end.column - 1 : 0;
|
||||||
return begin.toString ();
|
auto res = begin.toString ();
|
||||||
else
|
if (end.filename && begin.filename != end.filename)
|
||||||
return begin.toString () ~ "-" ~ end.toString ();
|
res ~= "-" ~ format("%s:%d.%d", end.filename, end.line, end_col);
|
||||||
|
else if (begin.line < end.line)
|
||||||
|
res ~= "-" ~ format("%d.%d", end.line, end_col);
|
||||||
|
else if (begin.column < end_col)
|
||||||
|
res ~= "-" ~ format("%d", end_col);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +300,7 @@ b4_user_union_members
|
|||||||
private static immutable int YYERRLAB1 = 7;
|
private static immutable int YYERRLAB1 = 7;
|
||||||
private static immutable int YYRETURN = 8;
|
private static immutable int YYRETURN = 8;
|
||||||
]b4_locations_if([
|
]b4_locations_if([
|
||||||
private static immutable YYSemanticType yy_semantic_null = cast(YYSemanticType)null;])[
|
private static immutable YYSemanticType yy_semantic_null;])[
|
||||||
private int yyerrstatus_ = 0;
|
private int yyerrstatus_ = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -141,27 +141,56 @@ class CalcLexer(R) : Lexer
|
|||||||
{
|
{
|
||||||
R input;
|
R input;
|
||||||
|
|
||||||
this(R r) { input = r; }
|
this(R r) {
|
||||||
|
input = r;
|
||||||
public void yyerror (string s)
|
|
||||||
{
|
|
||||||
stderr.writeln (s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YYSemanticType semanticVal_;
|
]AT_YYERROR_DEFINE[
|
||||||
|
|
||||||
|
YYSemanticType semanticVal_;]AT_LOCATION_IF([[
|
||||||
|
YYLocation location = new YYLocation;
|
||||||
|
|
||||||
|
public final @property YYPosition startPos()
|
||||||
|
{
|
||||||
|
return location.begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final @property YYPosition endPos()
|
||||||
|
{
|
||||||
|
return location.end;
|
||||||
|
}
|
||||||
|
]])[
|
||||||
public final @property YYSemanticType semanticVal()
|
public final @property YYSemanticType semanticVal()
|
||||||
{
|
{
|
||||||
return semanticVal_;
|
return semanticVal_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int yylex ()
|
int parseInt ()
|
||||||
{
|
{
|
||||||
|
auto res = 0;
|
||||||
|
import std.uni : isNumber;
|
||||||
|
while (input.front.isNumber)
|
||||||
|
{
|
||||||
|
res = res * 10 + (input.front - '0');]AT_LOCATION_IF([[
|
||||||
|
location.end.column += 1;]])[
|
||||||
|
input.popFront;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yylex ()
|
||||||
|
{]AT_LOCATION_IF([[
|
||||||
|
location.begin = location.end;]])[
|
||||||
|
|
||||||
import std.uni : isWhite, isNumber;
|
import std.uni : isWhite, isNumber;
|
||||||
|
|
||||||
// Skip initial spaces
|
// Skip initial spaces
|
||||||
while (!input.empty && input.front != '\n' && isWhite (input.front))
|
while (!input.empty && input.front != '\n' && isWhite (input.front))
|
||||||
input.popFront;
|
{
|
||||||
|
input.popFront;]AT_LOCATION_IF([[
|
||||||
|
location.begin.column += 1;
|
||||||
|
location.end.column += 1;]])[
|
||||||
|
}
|
||||||
|
|
||||||
// Handle EOF.
|
// Handle EOF.
|
||||||
if (input.empty)
|
if (input.empty)
|
||||||
@@ -170,13 +199,19 @@ class CalcLexer(R) : Lexer
|
|||||||
// Numbers.
|
// Numbers.
|
||||||
if (input.front.isNumber)
|
if (input.front.isNumber)
|
||||||
{
|
{
|
||||||
import std.conv : parse;
|
semanticVal_.ival = parseInt;
|
||||||
semanticVal_.ival = input.parse!int;
|
|
||||||
return YYTokenType.NUM;
|
return YYTokenType.NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Individual characters
|
// Individual characters
|
||||||
auto c = input.front;
|
auto c = input.front;]AT_LOCATION_IF([[
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
location.end.line += 1;
|
||||||
|
location.end.column = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
location.end.column += 1;]])[
|
||||||
input.popFront;
|
input.popFront;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -856,13 +891,13 @@ m4_define([AT_CHECK_CALC_LALR1_D],
|
|||||||
[AT_CHECK_CALC([%language "D" $1], [$2])])
|
[AT_CHECK_CALC([%language "D" $1], [$2])])
|
||||||
|
|
||||||
AT_CHECK_CALC_LALR1_D([])
|
AT_CHECK_CALC_LALR1_D([])
|
||||||
#AT_CHECK_CALC_LALR1_D([%locations])
|
AT_CHECK_CALC_LALR1_D([%locations])
|
||||||
#AT_CHECK_CALC_LALR1_D([%locations %define api.location.type {Span}])
|
#AT_CHECK_CALC_LALR1_D([%locations %define api.location.type {Span}])
|
||||||
AT_CHECK_CALC_LALR1_D([%define parse.error verbose %define api.prefix {calc} %verbose])
|
AT_CHECK_CALC_LALR1_D([%define parse.error verbose %define api.prefix {calc} %verbose])
|
||||||
|
|
||||||
#AT_CHECK_CALC_LALR1_D([%debug])
|
AT_CHECK_CALC_LALR1_D([%debug])
|
||||||
|
|
||||||
#AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %verbose])
|
AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %verbose])
|
||||||
#AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %define api.token.prefix {TOK_} %verbose])
|
#AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %define api.token.prefix {TOK_} %verbose])
|
||||||
|
|
||||||
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose %parse-param {semantic_value *result} %parse-param {int *count}])
|
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||||
|
|||||||
@@ -672,10 +672,9 @@ m4_define([AT_YYERROR_DECLARE_EXTERN(d)], [])
|
|||||||
|
|
||||||
m4_define([AT_YYERROR_DEFINE(d)],
|
m4_define([AT_YYERROR_DEFINE(d)],
|
||||||
[[/* An error reporting function. */
|
[[/* An error reporting function. */
|
||||||
public void error (]AT_LOCATION_IF([[location_type l, ]])[string m)
|
public void yyerror (]AT_LOCATION_IF([[YYLocation l, ]])[string m)
|
||||||
{
|
{
|
||||||
// FIXME: location.
|
stderr.writeln (]AT_LOCATION_IF([[l, ": ", ]])[m);
|
||||||
stderr.writeln (m);
|
|
||||||
}]])
|
}]])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user