d: add an example

* examples/d/calc.test, examples/d/calc.y, examples/d/local.mk:
This commit is contained in:
Akim Demaille
2018-11-30 08:17:57 +01:00
parent 0ebcae4a54
commit f15382f7d7
6 changed files with 227 additions and 3 deletions

26
examples/d/calc.test Normal file
View File

@@ -0,0 +1,26 @@
#! /bin/sh
# Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
cat >input <<EOF
1 + 2 * 3
EOF
run 0 7
cat >input <<EOF
1 + 2 * * 3
EOF
run 0 "err: syntax error, unexpected *, expecting - or ! or ( or number"

161
examples/d/calc.y Normal file
View File

@@ -0,0 +1,161 @@
%language "D"
%name-prefix "Calc"
%define parser_class_name {Calc}
%define public
%define parse.error verbose
%code imports {
import std.ascii;
import std.stdio;
}
%union {
int ival;
}
/* Bison Declarations */
%token EQ "="
PLUS "+"
MINUS "-"
STAR "*"
SLASH "/"
BANG "!"
LPAR "("
RPAR ")"
EOL "end of line"
%token <ival> NUM "number"
%type <ival> exp
%nonassoc "=" /* comparison */
%left "-" "+"
%left "*" "/"
%precedence NEG /* negation--unary minus */
/* Grammar follows */
%%
input:
line
| input line
;
line:
EOL
| exp EOL { writeln ($exp); }
| error EOL
;
exp:
NUM { $$ = $1; }
| exp "=" exp
{
if ($1 != $3)
yyerror (format ("calc: error: %d != %d", $1, $3));
}
| exp "+" exp { $$ = $1 + $3; }
| exp "-" exp { $$ = $1 - $3; }
| exp "*" exp { $$ = $1 * $3; }
| exp "/" exp { $$ = $1 / $3; }
| "-" exp %prec NEG { $$ = -$2; }
| "(" exp ")" { $$ = $2; }
| "(" error ")" { $$ = 1111; }
| "!" { $$ = 0; return YYERROR; }
| "-" error { $$ = 0; return YYERROR; }
;
%%
class CalcLexer : Lexer {
this ()
{}
int
get_char ()
{
import stdc = core.stdc.stdio;
return stdc.getc (stdc.stdin);
}
void
unget_char (int c)
{
import stdc = core.stdc.stdio;
stdc.ungetc (c, stdc.stdin);
}
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_;
}
YYTokenType 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;
}
switch (c)
{
case EOF: return YYTokenType.EOF;
case '=': return YYTokenType.EQ;
case '+': return YYTokenType.PLUS;
case '-': return YYTokenType.MINUS;
case '*': return YYTokenType.STAR;
case '/': return YYTokenType.SLASH;
case '!': return YYTokenType.BANG;
case '(': return YYTokenType.LPAR;
case ')': return YYTokenType.RPAR;
case '\n': return YYTokenType.EOL;
default: assert(0);
}
}
}
void main ()
{
CalcLexer l = new CalcLexer ();
Calc p = new Calc (l);
p.parse ();
}

35
examples/d/local.mk Normal file
View File

@@ -0,0 +1,35 @@
## Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
ddir = $(docdir)/%D%
## ------ ##
## Calc. ##
## ------ ##
if ENABLE_D
check_SCRIPTS += %D%/calc
TESTS += %D%/calc.test
endif
%D%/calc.d: %D%/calc.y $(BISON_IN) $(dist_pkgdata_DATA)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $< -o $@
%D%/calc: %D%/calc.d
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ $<
dist_d_DATA = %D%/calc.y
CLEANFILES += %D%/calc %D%/Calc.d

View File

@@ -77,6 +77,7 @@ CLEANDIRS += %D%/*.dSYM
include %D%/calc++/local.mk
include %D%/c++/local.mk
include %D%/d/local.mk
include %D%/java/local.mk
include %D%/mfcalc/local.mk
include %D%/rpcalc/local.mk