diff --git a/configure.ac b/configure.ac index 83e2c972..a9dad57c 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ BISON_CXX_COMPILER_POSIXLY_CORRECT # D. AC_CHECK_PROGS([DC], [dmd]) -AC_CHECK_PROGS([DCFLAGS], []) +AC_CHECK_PROGS([DCFLAGS], [-g]) AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x]) # Java. diff --git a/data/skeletons/d.m4 b/data/skeletons/d.m4 index 109c3a01..2d29127c 100644 --- a/data/skeletons/d.m4 +++ b/data/skeletons/d.m4 @@ -100,12 +100,6 @@ m4_define([b4_location_type_if], [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 # ----------------- m4_define([b4_identification], diff --git a/data/skeletons/lalr1.d b/data/skeletons/lalr1.d index 087b3a06..dc155ef4 100644 --- a/data/skeletons/lalr1.d +++ b/data/skeletons/lalr1.d @@ -97,12 +97,15 @@ public struct ]b4_position_type[ { /** The line number within an input file. */ public int line = 1; /** The name of the input file. */ - public string filename = "(unspecified file)"; + public string filename = null; /** * A string representation of the position. */ 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([[ @@ -141,6 +144,9 @@ public class ]b4_location_type[ this.begin = this.end = loc; } + public this () { + } + /** * Create a ]b4_location_type[ from the endpoints of the range. * @@param begin The first position included in the range. @@ -156,10 +162,15 @@ public class ]b4_location_type[ * ]b4_position_type[ should override the toString * method. */ public override string toString () const { - if (begin == end) - return begin.toString (); - else - return begin.toString () ~ "-" ~ end.toString (); + auto end_col = 0 < end.column ? end.column - 1 : 0; + auto res = begin.toString (); + if (end.filename && begin.filename != end.filename) + 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 YYRETURN = 8; ]b4_locations_if([ - private static immutable YYSemanticType yy_semantic_null = cast(YYSemanticType)null;])[ + private static immutable YYSemanticType yy_semantic_null;])[ private int yyerrstatus_ = 0; /** diff --git a/tests/calc.at b/tests/calc.at index 0036c10e..77537610 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -141,27 +141,56 @@ class CalcLexer(R) : Lexer { R input; - this(R r) { input = r; } - - public void yyerror (string s) - { - stderr.writeln (s); + this(R r) { + input = r; } - 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() { 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; // Skip initial spaces 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. if (input.empty) @@ -170,13 +199,19 @@ class CalcLexer(R) : Lexer // Numbers. if (input.front.isNumber) { - import std.conv : parse; - semanticVal_.ival = input.parse!int; + semanticVal_.ival = parseInt; return YYTokenType.NUM; } // 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; return c; } @@ -856,13 +891,13 @@ m4_define([AT_CHECK_CALC_LALR1_D], [AT_CHECK_CALC([%language "D" $1], [$2])]) 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([%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([%locations %define parse.error verbose %debug %verbose %parse-param {semantic_value *result} %parse-param {int *count}]) diff --git a/tests/local.at b/tests/local.at index 2b331cc9..48b65114 100644 --- a/tests/local.at +++ b/tests/local.at @@ -672,10 +672,9 @@ m4_define([AT_YYERROR_DECLARE_EXTERN(d)], []) m4_define([AT_YYERROR_DEFINE(d)], [[/* 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 (m); + stderr.writeln (]AT_LOCATION_IF([[l, ": ", ]])[m); }]])