bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]