summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2018-11-30 06:39:19 +0100
committerAkim Demaille <akim.demaille@gmail.com>2018-12-01 11:13:08 +0100
commitd2386a35f5a2c2bc10a03ba18319861d7bec0b9d (patch)
tree012b9b899a7bc7727a7c535834bc9924a1107b21
parent3422ee7435cf086a53bf9952e770c7eb4993b5f7 (diff)
downloadbison-d2386a35f5a2c2bc10a03ba18319861d7bec0b9d.tar.gz
java: add an example
* examples/java/Calc.y: New, based on test 495: "Calculator parse.error=verbose %locations". * examples/java/Calc.test, examples/java/local.mk: New. * configure.ac (ENABLE_JAVA): New. * examples/test (prog): Be ready to run Java programs.
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac1
-rw-r--r--examples/README6
-rw-r--r--examples/java/Calc.test26
-rw-r--r--examples/java/Calc.y166
-rw-r--r--examples/java/local.mk34
-rw-r--r--examples/local.mk1
-rwxr-xr-xexamples/test6
-rw-r--r--tests/local.mk2
9 files changed, 242 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 7f18f6f4..6911bc78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,7 @@ MOSTLYCLEANFILES =
SUFFIXES =
TESTS = $(dist_TESTS)
check_PROGRAMS =
+check_SCRIPTS =
dist_TESTS =
noinst_LIBRARIES =
diff --git a/configure.ac b/configure.ac
index 959fc968..cce792f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -280,6 +280,7 @@ AC_SUBST([GCC])
gt_JAVACOMP([1.7], [1.7])
gt_JAVAEXEC
+AM_CONDITIONAL([ENABLE_JAVA], [test x"$CONF_JAVAC" != x && test x"$CONF_JAVA" != x])
AC_CONFIG_FILES([Makefile
po/Makefile.in
diff --git a/examples/README b/examples/README
index 50ca4820..87f73544 100644
--- a/examples/README
+++ b/examples/README
@@ -34,6 +34,12 @@ Extracted from the documentation: "A Complete C++ Example".
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
+* Examples in Java
+
+** java/Calc.y
+The usual calculator.
+
+
-----
Local Variables:
diff --git a/examples/java/Calc.test b/examples/java/Calc.test
new file mode 100644
index 00000000..71861187
--- /dev/null
+++ b/examples/java/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: 1.5: syntax error, unexpected '*', expecting number or '-' or '(' or '!'"
diff --git a/examples/java/Calc.y b/examples/java/Calc.y
new file mode 100644
index 00000000..46c1dec2
--- /dev/null
+++ b/examples/java/Calc.y
@@ -0,0 +1,166 @@
+%language "Java"
+%name-prefix "Calc"
+%define parser_class_name {Calc}
+%define public
+
+%define parse.error verbose %locations
+%code {
+ public static void main (String args[]) throws IOException
+ {
+ CalcLexer l = new CalcLexer (System.in);
+ Calc p = new Calc (l);
+ p.parse ();
+ }
+}
+
+%code imports {
+ import java.io.StreamTokenizer;
+ import java.io.InputStream;
+ import java.io.InputStreamReader;
+ import java.io.Reader;
+ import java.io.IOException;
+}
+
+/* Bison Declarations */
+%token <Integer> NUM "number"
+%type <Integer> exp
+
+%nonassoc '=' /* comparison */
+%left '-' '+'
+%left '*' '/'
+%precedence NEG /* negation--unary minus */
+%right '^' /* exponentiation */
+
+/* Grammar follows */
+%%
+input:
+ line
+| input line
+;
+
+line:
+ '\n'
+| exp '\n' { System.out.println ($exp); }
+| error '\n'
+;
+
+exp:
+ NUM { $$ = $1; }
+| exp '=' exp
+ {
+ if ($1.intValue () != $3.intValue ())
+ yyerror (@$, "calc: error: " + $1 + " != " + $3);
+ }
+| exp '+' exp { $$ = new Integer ($1.intValue () + $3.intValue ()); }
+| exp '-' exp { $$ = new Integer ($1.intValue () - $3.intValue ()); }
+| exp '*' exp { $$ = new Integer ($1.intValue () * $3.intValue ()); }
+| exp '/' exp { $$ = new Integer ($1.intValue () / $3.intValue ()); }
+| '-' exp %prec NEG { $$ = new Integer (-$2.intValue ()); }
+| exp '^' exp { $$ = new Integer ((int)
+ Math.pow ($1.intValue (),
+ $3.intValue ())); }
+| '(' exp ')' { $$ = $2; }
+| '(' error ')' { $$ = new Integer (1111); }
+| '!' { $$ = new Integer (0); return YYERROR; }
+| '-' error { $$ = new Integer (0); return YYERROR; }
+;
+
+
+%%
+class CalcLexer implements Calc.Lexer {
+
+ StreamTokenizer st;
+
+ public CalcLexer (InputStream is)
+ {
+ st = new StreamTokenizer (new InputStreamReader (is));
+ st.resetSyntax ();
+ st.eolIsSignificant (true);
+ st.whitespaceChars (9, 9);
+ st.whitespaceChars (32, 32);
+ st.wordChars (48, 57);
+ }
+
+
+ Position yypos = new Position (1, 0);
+
+ public Position getStartPos () {
+ return yypos;
+ }
+
+ public Position getEndPos () {
+ return yypos;
+ }
+
+ public void yyerror (Calc.Location l, String s)
+ {
+ if (l == null)
+ System.err.println (s);
+ else
+ System.err.println (l + ": " + s);
+ }
+
+
+ Integer yylval;
+
+ public Object getLVal () {
+ return yylval;
+ }
+
+ public int yylex () throws IOException {
+ int ttype = st.nextToken ();
+ yypos = new Position (yypos.lineno (), yypos.token () + 1);
+ if (ttype == st.TT_EOF)
+ return EOF;
+ else if (ttype == st.TT_EOL)
+ {
+ yypos = new Position (yypos.lineno () + 1, 0);
+ return (int) '\n';
+ }
+ else if (ttype == st.TT_WORD)
+ {
+ yylval = new Integer (st.sval);
+ return NUM;
+ }
+ else
+ return st.ttype;
+ }
+}
+
+
+class Position {
+ public int line;
+ public int token;
+
+ public Position ()
+ {
+ line = 0;
+ token = 0;
+ }
+
+ public Position (int l, int t)
+ {
+ line = l;
+ token = t;
+ }
+
+ public boolean equals (Position l)
+ {
+ return l.line == line && l.token == token;
+ }
+
+ public String toString ()
+ {
+ return Integer.toString (line) + "." + Integer.toString(token);
+ }
+
+ public int lineno ()
+ {
+ return line;
+ }
+
+ public int token ()
+ {
+ return token;
+ }
+}
diff --git a/examples/java/local.mk b/examples/java/local.mk
new file mode 100644
index 00000000..56e71630
--- /dev/null
+++ b/examples/java/local.mk
@@ -0,0 +1,34 @@
+## 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/>.
+
+javadir = $(docdir)/%D%
+
+## ------ ##
+## Calc. ##
+## ------ ##
+
+if ENABLE_JAVA
+ check_SCRIPTS += %D%/Calc.class
+ TESTS += %D%/Calc.test
+endif
+
+%D%/Calc.java: %D%/Calc.y $(BISON_IN) $(dist_pkgdata_DATA)
+ $(AM_V_GEN)$(BISON) $< -o $@
+
+%D%/Calc.class: %D%/Calc.java
+ $(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh $<
+
+dist_java_DATA = %D%/Calc.y
+CLEANFILES += %D%/Calc.class %D%/Calc.java
diff --git a/examples/local.mk b/examples/local.mk
index 6db28dce..4763221d 100644
--- a/examples/local.mk
+++ b/examples/local.mk
@@ -77,5 +77,6 @@ CLEANDIRS += %D%/*.dSYM
include %D%/calc++/local.mk
include %D%/c++/local.mk
+include %D%/java/local.mk
include %D%/mfcalc/local.mk
include %D%/rpcalc/local.mk
diff --git a/examples/test b/examples/test
index 96db4e7f..d9177cb1 100755
--- a/examples/test
+++ b/examples/test
@@ -33,6 +33,10 @@ do
if test -x "$p"; then
prog=$p
break
+ elif test -f "$p.class"; then
+ pwd
+ prog="$SHELL $cwd/javaexec.sh -cp $(dirname $p) $(basename $p)"
+ break
fi
done
if test x"$prog" = x; then
@@ -82,10 +86,12 @@ run ()
echo "$me: PASS: $number"
else
echo "$me: FAIL: $number (expected output: $out_exp, effective: $out_eff)"
+ cat err_eff
exit=false
fi
else
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
+ cat err_eff
exit=false
fi
number=$(expr $number + 1)
diff --git a/tests/local.mk b/tests/local.mk
index e2245dab..497c7dc8 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -85,7 +85,7 @@ $(TESTSUITE): $(TESTSUITE_AT)
# Move into %D%/ so that testsuite.dir etc. be created there.
RUN_TESTSUITE = $(TESTSUITE) -C %D% $(TESTSUITEFLAGS)
-check_SCRIPTS = $(BISON) %D%/atconfig %D%/atlocal
+check_SCRIPTS += $(BISON) %D%/atconfig %D%/atlocal
RUN_TESTSUITE_deps = all $(TESTSUITE) $(check_SCRIPTS)
clean-local: clean-local-tests