mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
dlang: initial changes to run the calc tests on it
* configure.ac (DCFLAGS): Define. * tests/atlocal.in: Receive it. * data/skeletons/d.m4 (api.parser.class): Remove spurious YY. * data/skeletons/lalr1.d (yylex): Return an int instead of a YYTokenType, so that we can use characters as tokens. * examples/d/calc.y: Adjust. * tests/local.at: Initial support for D. (AT_D_IF, AT_DATA_GRAMMAR(D), AT_YYERROR_DECLARE(d)) (AT_YYERROR_DECLARE_EXTERN(d), AT_YYERROR_DEFINE(d)) (AT_MAIN_DEFINE(d), AT_COMPILE_D, AT_LANG_COMPILE(d), AT_LANG_EXT(d)): New. * tests/calc.at: Initial support for D. * tests/headers.at
This commit is contained in:
@@ -192,6 +192,7 @@ BISON_CXX_COMPILER_POSIXLY_CORRECT
|
||||
|
||||
# D.
|
||||
AC_CHECK_PROGS([DC], [dmd])
|
||||
AC_CHECK_PROGS([DCFLAGS], [])
|
||||
AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x])
|
||||
|
||||
# Java.
|
||||
|
||||
@@ -190,7 +190,7 @@ b4_percent_define_default([[stype]], [[YYSemanticType]])])
|
||||
# %name-prefix
|
||||
m4_define_default([b4_prefix], [[YY]])
|
||||
|
||||
b4_percent_define_default([[api.parser.class]], [b4_prefix[]YYParser])])
|
||||
b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser])])
|
||||
m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])])
|
||||
|
||||
#b4_percent_define_default([[location_type]], [Location])])
|
||||
|
||||
@@ -69,7 +69,7 @@ public interface Lexer
|
||||
* to the next token and prepares to return the semantic value
|
||||
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
||||
* @@return the token identifier corresponding to the next token. */
|
||||
YYTokenType yylex ();
|
||||
int yylex ();
|
||||
|
||||
/**
|
||||
* Entry point for error reporting. Emits an error
|
||||
|
||||
@@ -108,7 +108,7 @@ class CalcLexer : Lexer {
|
||||
return semanticVal_;
|
||||
}
|
||||
|
||||
YYTokenType yylex ()
|
||||
int yylex ()
|
||||
{
|
||||
int c;
|
||||
/* Skip white spaces. */
|
||||
|
||||
@@ -118,6 +118,9 @@ fi
|
||||
## Other. ##
|
||||
## ------- ##
|
||||
|
||||
: ${DC='@DC@'}
|
||||
: ${DCFLAGS='@DCFLAGS@'}
|
||||
|
||||
# Empty if no javac was found
|
||||
: ${CONF_JAVAC='@CONF_JAVAC@'}
|
||||
|
||||
|
||||
170
tests/calc.at
170
tests/calc.at
@@ -44,11 +44,28 @@ m4_define([_AT_DATA_CALC_Y],
|
||||
[m4_if([$1$2$3], $[1]$[2]$[3], [],
|
||||
[m4_fatal([$0: Invalid arguments: $@])])dnl
|
||||
|
||||
m4_pushdef([AT_CALC_MAIN],
|
||||
[#include <assert.h>
|
||||
AT_D_IF([m4_pushdef([AT_CALC_MAIN],
|
||||
[[int main (string[] args)
|
||||
{
|
||||
semantic_value result = 0;
|
||||
int count = 0;
|
||||
|
||||
if (args.length == 2)
|
||||
input = File (args[1], "r");
|
||||
else
|
||||
input = stdin;
|
||||
|
||||
CalcLexer l = new CalcLexer ();
|
||||
YYParser p = new YYParser (l);
|
||||
int status = !p.parse ();
|
||||
return status;
|
||||
}
|
||||
]])],
|
||||
[m4_pushdef([AT_CALC_MAIN],
|
||||
[[#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
AT_CXX_IF([[
|
||||
]AT_CXX_IF([[
|
||||
namespace
|
||||
{
|
||||
/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */
|
||||
@@ -101,10 +118,103 @@ main (int argc, const char **argv)
|
||||
assert (global_count == count); (void) count;
|
||||
return status;
|
||||
}
|
||||
]])
|
||||
]])])
|
||||
|
||||
AT_D_IF([m4_pushdef([AT_CALC_LEX],
|
||||
[[File input;
|
||||
|
||||
m4_pushdef([AT_CALC_LEX],
|
||||
class CalcLexer : Lexer {
|
||||
|
||||
int prev_char = -1;
|
||||
|
||||
int
|
||||
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)
|
||||
{
|
||||
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_;
|
||||
|
||||
public final @property YYSemanticType semanticVal()
|
||||
{
|
||||
return semanticVal_;
|
||||
}
|
||||
|
||||
int yylex ()
|
||||
{
|
||||
int c;
|
||||
/* Skip white spaces. */
|
||||
do
|
||||
{}
|
||||
while ((c = get_char ()) == ' ' || c == '\t');
|
||||
|
||||
/* process numbers */
|
||||
if (c == '.' || isDigit (c))
|
||||
{
|
||||
unget_char (c);
|
||||
semanticVal_.ival = read_signed_integer ();
|
||||
return YYTokenType.NUM;
|
||||
}
|
||||
|
||||
/* Return end-of-file. */
|
||||
if (c == EOF)
|
||||
{
|
||||
return YYTokenType.EOF;
|
||||
}
|
||||
|
||||
/* Return single chars. */
|
||||
return c;
|
||||
}
|
||||
}
|
||||
]])],
|
||||
[m4_pushdef([AT_CALC_LEX],
|
||||
[[#include <ctype.h>
|
||||
|
||||
]AT_YYLEX_DECLARE_EXTERN[
|
||||
@@ -202,12 +312,19 @@ read_signed_integer (]AT_YYLEX_FORMALS[)
|
||||
return c;
|
||||
}
|
||||
]])
|
||||
])
|
||||
|
||||
AT_DATA_GRAMMAR([calc.y],
|
||||
[[/* Infix notation calculator--calc */
|
||||
]$4
|
||||
AT_CXX_IF(
|
||||
[%define global_tokens_and_yystype])[
|
||||
]$4[
|
||||
]AT_CXX_IF([%define global_tokens_and_yystype])[
|
||||
]AT_D_IF([[
|
||||
%code imports {
|
||||
import std.ascii;
|
||||
import std.stdio;
|
||||
alias semantic_value = int;
|
||||
}
|
||||
]], [[
|
||||
%code requires
|
||||
{
|
||||
]AT_LOCATION_TYPE_SPAN_IF([[
|
||||
@@ -241,6 +358,7 @@ AT_CXX_IF(
|
||||
/* Exercise pre-prologue dependency to %union. */
|
||||
typedef int semantic_value;
|
||||
}
|
||||
]])[
|
||||
|
||||
/* Exercise %union. */
|
||||
%union
|
||||
@@ -250,6 +368,7 @@ AT_CXX_IF(
|
||||
%printer { ]AT_CXX_IF([[yyo << $$]],
|
||||
[[fprintf (yyo, "%d", $$)]])[; } <ival>;
|
||||
|
||||
]AT_D_IF([], [[
|
||||
%code provides
|
||||
{
|
||||
#include <stdio.h>
|
||||
@@ -271,6 +390,7 @@ static int power (int base, int exponent);
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE_EXTERN[
|
||||
}
|
||||
]])[
|
||||
|
||||
]AT_LOCATION_TYPE_SPAN_IF([[
|
||||
%initial-action
|
||||
@@ -299,15 +419,17 @@ input:
|
||||
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1], [USE ($1)])[; }
|
||||
| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1;], [AT_D_IF([], [USE ($1);])])[ }
|
||||
;
|
||||
|
||||
exp:
|
||||
NUM
|
||||
| exp '=' exp
|
||||
{
|
||||
if ($1 != $3)
|
||||
fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
|
||||
if ($1 != $3)]AT_D_IF([
|
||||
stderr.writefln ("calc: error: %d != %d", $1, $3);], [
|
||||
fprintf (stderr, "calc: error: %d != %d\n", $1, $3);], [
|
||||
])[
|
||||
$$ = $1;
|
||||
}
|
||||
| exp '+' exp { $$ = $1 + $3; }
|
||||
@@ -317,9 +439,9 @@ exp:
|
||||
| '-' exp %prec NEG { $$ = -$2; }
|
||||
| exp '^' exp { $$ = power ($1, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
| '(' error ')' { $$ = 1111; yyerrok; }
|
||||
| '!' { $$ = 0; YYERROR; }
|
||||
| '-' error { $$ = 0; YYERROR; }
|
||||
| '(' error ')' { $$ = 1111; ]AT_D_IF([], [yyerrok;])[ }
|
||||
| '!' { $$ = 0; ]AT_D_IF([return YYERROR], [YYERROR])[; }
|
||||
| '-' error { $$ = 0; ]AT_D_IF([return YYERROR], [YYERROR])[; }
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -730,3 +852,23 @@ AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %de
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
|
||||
# --------------------------- #
|
||||
# Simple LALR1 D Calculator. #
|
||||
# --------------------------- #
|
||||
|
||||
AT_BANNER([[Simple LALR(1) D Calculator.]])
|
||||
|
||||
# First let's try using %skeleton
|
||||
AT_CHECK_CALC([%skeleton "lalr1.d"])
|
||||
|
||||
# AT_CHECK_CALC_LALR1_D([BISON-OPTIONS])
|
||||
# ---------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# the C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR1_D],
|
||||
[AT_CHECK_CALC([%language "D" $1], [$2])])
|
||||
|
||||
AT_CHECK_CALC_LALR1_D([])
|
||||
@@ -147,13 +147,16 @@ m4_pushdef([AT_DEBUG_IF],
|
||||
[m4_bmatch([$3], [%debug\|%define parse.trace], [$1], [$2])])
|
||||
m4_pushdef([AT_CXX_IF],
|
||||
[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
|
||||
m4_pushdef([AT_D_IF],
|
||||
[m4_bmatch([$3], [%language "[Dd]"\|%skeleton "[a-z0-9]+\.d"], [$1], [$2])])
|
||||
m4_pushdef([AT_JAVA_IF],
|
||||
[m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])])
|
||||
# The target language: "c", "c++", or "java".
|
||||
m4_pushdef([AT_LANG],
|
||||
[AT_JAVA_IF([java],
|
||||
[AT_CXX_IF([c++],
|
||||
[c])])])
|
||||
[AT_D_IF([d],
|
||||
[c])])])])
|
||||
m4_pushdef([AT_GLR_IF],
|
||||
[m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])])
|
||||
m4_pushdef([AT_LALR1_CC_IF],
|
||||
@@ -633,6 +636,40 @@ done
|
||||
CXXFLAGS=$at_for_each_std_CXXFLAGS_save
|
||||
]])
|
||||
|
||||
|
||||
|
||||
## --- ##
|
||||
## D. ##
|
||||
## --- ##
|
||||
|
||||
# AT_DATA_GRAMMAR(NAME, CONTENT)
|
||||
# ------------------------------
|
||||
m4_copy([AT_DATA], [AT_DATA_GRAMMAR(d)])
|
||||
|
||||
|
||||
# No need to declare, it's part of the class interface.
|
||||
m4_define([AT_YYERROR_DECLARE(d)], [])
|
||||
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)
|
||||
{
|
||||
// FIXME: location.
|
||||
stderr.writeln (m);
|
||||
}]])
|
||||
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(d)],
|
||||
[[int main ()
|
||||
{
|
||||
Lexer l = new Lexer ();
|
||||
Parser p = new Parser (l);
|
||||
p.parse ();
|
||||
}]])
|
||||
|
||||
|
||||
|
||||
## ------ ##
|
||||
## Java. ##
|
||||
## ------ ##
|
||||
@@ -921,6 +958,25 @@ AT_CHECK(m4_join([ ],
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_COMPILE_D(OUTPUT, [SOURCES = OUTPUT.d], [EXTRA-COMPILER-FLAGS])
|
||||
# -------------------------------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. If the C++ compiler does not work,
|
||||
# ignore the test.
|
||||
#
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing ".o" removed, and ".cc" appended.
|
||||
m4_define([AT_COMPILE_D],
|
||||
[AT_KEYWORDS(d)
|
||||
AT_CHECK(m4_join([ ],
|
||||
[$DC $DCFLAGS $3],
|
||||
[m4_bmatch([$1], [[.]], [-c])],
|
||||
[-of$1],
|
||||
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).d])],
|
||||
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_JAVA_COMPILE(SOURCES)
|
||||
# ------------------------
|
||||
# Compile SOURCES into Java class files. Skip the test if java or javac
|
||||
@@ -948,6 +1004,7 @@ m4_define([AT_LANG_FOR_EACH_STD], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2], [$3])])
|
||||
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2], [$3])])
|
||||
m4_define([AT_LANG_COMPILE(d)], [AT_COMPILE_D([$1], [$2], [$3])])
|
||||
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2], [$3])])
|
||||
|
||||
|
||||
@@ -957,6 +1014,7 @@ m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2], [$3])])
|
||||
m4_define([AT_LANG_EXT], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_EXT(c)], [c])
|
||||
m4_define([AT_LANG_EXT(c++)], [cc])
|
||||
m4_define([AT_LANG_EXT(d)], [d])
|
||||
m4_define([AT_LANG_EXT(java)], [java])
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user