mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
Fix syntax error regarding interface inheritance of the Lexer. It appeared when the `%code lexer` option was used. Reported by ledaniel2. <https://github.com/akimd/bison/issues/84> * data/skeletons/lalr1.d: Fix syntax. * tests/d.at: Test it.
163 lines
4.5 KiB
Plaintext
163 lines
4.5 KiB
Plaintext
# D features tests. -*- Autotest -*-
|
|
|
|
# Copyright (C) 2020-2022 Free Software Foundation, Inc.
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
AT_BANNER([[D Features.]])
|
|
|
|
# AT_CHECK_D_MINIMAL([DIRECTIVES], [PARSER_ACTION], [POSITION_CLASS], [EXTRA_USER_CODE])
|
|
# ----------------------------------------------------------------------
|
|
# Check that a minimal parser with DIRECTIVES compiles in D.
|
|
# Put the D code in YYParser.d.
|
|
m4_define([AT_CHECK_D_MINIMAL],
|
|
[
|
|
AT_DATA([[YYParser.y]], [
|
|
%language "D"
|
|
%token END "end"
|
|
[$1]
|
|
%%
|
|
start: END {$2};
|
|
%%
|
|
[$4]
|
|
void main() {}
|
|
])
|
|
AT_BISON_CHECK([[-Wno-deprecated YYParser.y]])
|
|
AT_CHECK([[grep '[mb]4_' YYParser.y]], [1], [ignore])
|
|
AT_COMPILE_D([[YYParser]])
|
|
])
|
|
|
|
# AT_CHECK_D_MINIMAL_W_LEXER([1:DIRECTIVES],
|
|
# [2:YYLEX_ACTION], [3:LEXER_BODY], [4:PARSER_ACTION], [5:VALUE_TYPE],
|
|
# [6:POSITION_TYPE], [7:LOCATION_TYPE])
|
|
# ---------------------------------------------------------------------
|
|
# Check that a minimal parser with DIRECTIVES and a body for yylex()
|
|
# compiles in D.
|
|
m4_define([AT_CHECK_D_MINIMAL_W_LEXER],
|
|
[AT_CHECK_D_MINIMAL([$1], [], [], [
|
|
|
|
import std.range.primitives;
|
|
import std.stdio;
|
|
|
|
auto calcLexer(R)(R range)
|
|
if (isInputRange!R && is (ElementType!R : dchar))
|
|
{
|
|
return new CalcLexer!R(range);
|
|
}
|
|
|
|
auto calcLexer (File f)
|
|
{
|
|
import std.algorithm : map, joiner;
|
|
import std.utf : byDchar;
|
|
|
|
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
|
|
}
|
|
|
|
class CalcLexer(R) : Lexer
|
|
if (isInputRange!R && is (ElementType!R : dchar))
|
|
{
|
|
R input;
|
|
|
|
this(R r) {
|
|
input = r;
|
|
}
|
|
|
|
void yyerror(string s) {}
|
|
|
|
Symbol yylex()
|
|
{
|
|
$2
|
|
}
|
|
}
|
|
]
|
|
[
|
|
$3
|
|
], [$4], [$6])])
|
|
|
|
# AT_CHECK_D_GREP([LINE], [COUNT=1])
|
|
# -------------------------------------
|
|
# Check that YYParser.d contains exactly COUNT lines matching ^LINE$
|
|
# with grep.
|
|
m4_define([AT_CHECK_D_GREP],
|
|
[AT_CHECK([grep -c '^$1$' YYParser.d], [ignore], [m4_default([$2], [1])
|
|
])])
|
|
|
|
## -------------------------------------- ##
|
|
## D parser class extends and implements. ##
|
|
## -------------------------------------- ##
|
|
|
|
AT_SETUP([D parser class extends and implements])
|
|
AT_KEYWORDS([d])
|
|
|
|
AT_CHECK_D_MINIMAL([])
|
|
AT_CHECK_D_GREP([[class YYParser]])
|
|
|
|
AT_CHECK_D_MINIMAL([%define api.parser.extends {BaseClass}], [], [], [class BaseClass {}])
|
|
AT_CHECK_D_GREP([[class YYParser : BaseClass]])
|
|
|
|
AT_CHECK_D_MINIMAL([%define api.parser.extends {Interface}], [], [], [interface Interface {}])
|
|
AT_CHECK_D_GREP([[class YYParser : Interface]])
|
|
|
|
AT_CHECK_D_MINIMAL([%code lexer
|
|
{
|
|
Symbol yylex () {return Symbol();}
|
|
void yyerror (string s) {import std.stdio;writeln(s);}
|
|
}], [], [], [])
|
|
AT_CHECK_D_GREP([[private class YYLexer: Lexer]])
|
|
|
|
AT_CHECK_D_MINIMAL(
|
|
[%define api.parser.extends {BaseClass}
|
|
%define api.parser.implements {Interface}], [], [],
|
|
[class BaseClass {}
|
|
interface Interface {}
|
|
])
|
|
AT_CHECK_D_GREP([[class YYParser : BaseClass, Interface]])
|
|
|
|
AT_CHECK_D_MINIMAL(
|
|
[%define api.parser.extends {BaseClass}
|
|
%define api.parser.implements {Interface1, Interface2}], [], [],
|
|
[class BaseClass {}
|
|
interface Interface1 {}
|
|
interface Interface2 {}
|
|
])
|
|
AT_CHECK_D_GREP([[class YYParser : BaseClass, Interface1, Interface2]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## --------------------------------------------- ##
|
|
## D parser class api.token.raw true by default. ##
|
|
## --------------------------------------------- ##
|
|
|
|
AT_SETUP([D parser class api.token.raw true by default])
|
|
AT_KEYWORDS([d])
|
|
|
|
AT_CHECK_D_MINIMAL_W_LEXER([
|
|
%define api.token.raw true
|
|
%union { int ival; }], [return Symbol(TokenKind.END);])
|
|
AT_CHECK_D_GREP([[ END = 3,]])
|
|
|
|
AT_CHECK_D_MINIMAL_W_LEXER([
|
|
%define api.token.raw false
|
|
%union { int ival; }], [return Symbol(TokenKind.END);])
|
|
AT_CHECK_D_GREP([[ END = 258,]])
|
|
|
|
AT_CHECK_D_MINIMAL_W_LEXER([
|
|
%union { int ival; }], [return Symbol(TokenKind.END);])
|
|
AT_CHECK_D_GREP([[ END = 3,]])
|
|
|
|
AT_CLEANUP
|