[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] d: add an example
From: |
Akim Demaille |
Subject: |
[PATCH 4/5] d: add an example |
Date: |
Tue, 4 Dec 2018 21:14:39 +0100 |
* examples/d/calc.test, examples/d/calc.y, examples/d/local.mk:
---
configure.ac | 3 +-
examples/d/calc.test | 26 +++++++
examples/d/calc.y | 161 +++++++++++++++++++++++++++++++++++++++++++
examples/d/local.mk | 35 ++++++++++
examples/local.mk | 1 +
tests/calc.at | 4 +-
6 files changed, 227 insertions(+), 3 deletions(-)
create mode 100644 examples/d/calc.test
create mode 100644 examples/d/calc.y
create mode 100644 examples/d/local.mk
diff --git a/configure.ac b/configure.ac
index f0d5a585..61b07ca1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -189,7 +189,8 @@ BISON_TEST_FOR_WORKING_CXX_COMPILER
BISON_CXX_COMPILER_POSIXLY_CORRECT
# D.
-AM_CONDITIONAL([ENABLE_D], [true])
+AC_CHECK_PROGS([DC], [dmd])
+AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x])
# Java.
gt_JAVACOMP([1.7], [1.7])
diff --git a/examples/d/calc.test b/examples/d/calc.test
new file mode 100644
index 00000000..3a067e05
--- /dev/null
+++ b/examples/d/calc.test
@@ -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"
diff --git a/examples/d/calc.y b/examples/d/calc.y
new file mode 100644
index 00000000..320e7427
--- /dev/null
+++ b/examples/d/calc.y
@@ -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 ();
+}
+
diff --git a/examples/d/local.mk b/examples/d/local.mk
new file mode 100644
index 00000000..d5d9ac9d
--- /dev/null
+++ b/examples/d/local.mk
@@ -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
diff --git a/examples/local.mk b/examples/local.mk
index 3c7efff5..0fd81b5c 100644
--- a/examples/local.mk
+++ b/examples/local.mk
@@ -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
diff --git a/tests/calc.at b/tests/calc.at
index d4c817d6..d602797b 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -176,7 +176,7 @@ read_signed_integer (]AT_YYLEX_FORMALS[)
]AT_YYLEX_PROTOTYPE[
{
int c;
- /* Skip current token, then white spaces. */
+ /* Skip white spaces. */
do
{
]AT_LOCATION_IF(
@@ -186,7 +186,7 @@ read_signed_integer (]AT_YYLEX_FORMALS[)
}
while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t');
- /* process numbers */
+ /* Process numbers */
if (c == '.' || isdigit (c))
{
unget_char (]AT_YYLEX_PRE_ARGS[ c);
--
2.19.2
- [PATCH 0/5] add experimental support for the D programming language, Akim Demaille, 2018/12/04
- [PATCH 2/5] d: add experimental support for the D language, Akim Demaille, 2018/12/04
- [PATCH 5/5] java, d: compute static subtractions, Akim Demaille, 2018/12/04
- [PATCH 4/5] d: add an example,
Akim Demaille <=
- [PATCH 3/5] d: update the skeleton, Akim Demaille, 2018/12/04
- [PATCH 1/5] d: add skeleton for the D language, Akim Demaille, 2018/12/04