d: tests: use more a natural approach for the scanner

See f8408562f8.

* tests/calc.at: Stop imitating the C API.
Prepare more tests to run in the future.
%verbose works as expected (what a surprise, it's unrelated to the
skeleton...).
This commit is contained in:
Akim Demaille
2019-03-02 10:22:00 +01:00
parent 941cdf921d
commit 225bc5836a

View File

@@ -51,10 +51,9 @@ AT_D_IF([m4_pushdef([AT_CALC_MAIN],
int count = 0; int count = 0;
File input = args.length == 2 ? File (args[1], "r") : stdin; File input = args.length == 2 ? File (args[1], "r") : stdin;
CalcLexer l = new CalcLexer (input); auto l = calcLexer (input);
YYParser p = new YYParser (l); auto p = new YYParser (l);
int status = !p.parse (); return !p.parse ();
return status;
} }
]])], ]])],
[m4_pushdef([AT_CALC_MAIN], [m4_pushdef([AT_CALC_MAIN],
@@ -117,71 +116,38 @@ main (int argc, const char **argv)
]])]) ]])])
AT_D_IF([m4_pushdef([AT_CALC_LEX], AT_D_IF([m4_pushdef([AT_CALC_LEX],
[[class CalcLexer : Lexer [[import std.range.primitives;
import std.stdio;
auto calcLexer(R)(R range)
if (isInputRange!R && is (ElementType!R : dchar))
{ {
return new CalcLexer!R(range);
}
this (File i) auto calcLexer (File f)
{ {
input = i; import std.algorithm : map, joiner;
} import std.utf : byDchar;
File input; return f.byChunk(1024) // avoid making a syscall roundtrip per char
.map!(chunk => cast(char[]) chunk) // because byChunk returns ubyte[]
.joiner // combine chunks into a single virtual range of char
.calcLexer; // forward to other overload
}
int prev_char = -1; class CalcLexer(R) : Lexer
if (isInputRange!R && is (ElementType!R : dchar))
{
R input;
int this(R r) { input = r; }
get_char ()
{
if (prev_char != -1)
{
auto res = prev_char;
prev_char = -1;
return res;
}
else
{
auto res = input.rawRead (new char[1]);
if (res.length == 0)
return -1;
else
return res[0];
}
}
void
unget_char (int c)
{
prev_char = c;
}
public void yyerror (string s) public void yyerror (string s)
{ {
stderr.writeln (s); stderr.writeln (s);
} }
int
read_signed_integer ()
{
int c = get_char ();
int sign = 1;
int n = 0;
if (c == '-')
{
c = get_char ();
sign = -1;
}
while (isDigit (c))
{
n = 10 * n + (c - '0');
c = get_char ();
}
unget_char (c);
return sign * n;
}
YYSemanticType semanticVal_; YYSemanticType semanticVal_;
public final @property YYSemanticType semanticVal() public final @property YYSemanticType semanticVal()
@@ -191,27 +157,27 @@ AT_D_IF([m4_pushdef([AT_CALC_LEX],
int yylex () int yylex ()
{ {
int c; import std.uni : isWhite, isNumber;
/* Skip white spaces. */
do
{}
while ((c = get_char ()) == ' ' || c == '\t');
/* process numbers */ // Skip initial spaces
if (c == '.' || isDigit (c)) while (!input.empty && input.front != '\n' && isWhite (input.front))
input.popFront;
// Handle EOF.
if (input.empty)
return YYTokenType.EOF;
// Numbers.
if (input.front == '.' || input.front.isNumber)
{ {
unget_char (c); import std.conv : parse;
semanticVal_.ival = read_signed_integer (); semanticVal_.ival = input.parse!int;
return YYTokenType.NUM; return YYTokenType.NUM;
} }
/* Return end-of-file. */ // Individual characters
if (c == EOF) auto c = input.front;
{ input.popFront;
return YYTokenType.EOF;
}
/* Return single chars. */
return c; return c;
} }
} }
@@ -874,3 +840,14 @@ 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 %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([%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}])
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %parse-param {semantic_value *result} %parse-param {int *count}])