Initial checkin of Jade.
authorJayant DeSouza <jdesouza@uiuc.edu>
Tue, 9 Mar 2004 21:00:38 +0000 (21:00 +0000)
committerJayant DeSouza <jdesouza@uiuc.edu>
Tue, 9 Mar 2004 21:00:38 +0000 (21:00 +0000)
doc/jade/Makefile [new file with mode: 0644]
doc/jade/manual.tex [new file with mode: 0644]
src/langs/jade/JArray.C [new file with mode: 0644]
src/langs/jade/JArray.h [new file with mode: 0644]
src/langs/jade/Makefile [new file with mode: 0644]
src/langs/jade/jade.h [new file with mode: 0644]
src/langs/jade/java.g [new file with mode: 0644]
src/langs/jade/java.tree.g [new file with mode: 0644]
src/langs/jade/java.tree1.g [new file with mode: 0644]
src/scripts/Makefile

diff --git a/doc/jade/Makefile b/doc/jade/Makefile
new file mode 100644 (file)
index 0000000..df641ed
--- /dev/null
@@ -0,0 +1,11 @@
+# Stub makefile for LaTeX PPL manual
+FILE=manual
+TEX=$(FILE).tex
+DEST=jade
+LATEX2HTML=$(L2H) -split 4
+PROJECT_LINK='<a href="http://charm.cs.uiuc.edu/research/jade">Jade Homepage</a><br>'
+
+include ../Makefile.common
+
+index.tex:
+       touch index.tex
diff --git a/doc/jade/manual.tex b/doc/jade/manual.tex
new file mode 100644 (file)
index 0000000..ef33251
--- /dev/null
@@ -0,0 +1,229 @@
+\documentclass[10pt]{article}
+\usepackage{../pplmanual}
+\input{../pplmanual}
+
+\title{Jade Language Manual}
+\version{1.0}
+\credits{
+Jade was developed by Jayant DeSouza.
+}
+
+\begin{document}
+\maketitle
+
+\section{Introduction}
+
+This manual describes \jade, which is a new parallel programming language
+developed over \charmpp{} and Java. \charmpp{} is a
+\CC{}-based parallel programming library developed by Prof. L. V. Kal\'{e} 
+and his students over the last 10 years at University of Illinois.
+
+We first describe our philosophy behind this work (why we do what we do).
+Later we give a brief introduction to \charmpp{} and rationale for \jade. We
+describe \jade in detail. Appendices contain the gory details of installing
+\jade, building and running \jade programs.
+
+\subsection{Our Philosophy}
+
+\subsection{Terminology}
+
+\begin{description}
+
+\item[Module] A module refers to 
+
+\item[Thread] A thread is a lightweight process that owns a stack and machine
+registers including program counter, but shares code and data with other
+threads within the same address space. If the underlying operating system
+recognizes a thread, it is known as kernel thread, otherwise it is known as
+user-thread. A context-switch between threads refers to suspending one thread's
+execution and transferring control to another thread. Kernel threads typically
+have higher context switching costs than user-threads because of operating
+system overheads. The policy implemented by the underlying system for
+transferring control between threads is known as thread scheduling policy.
+Scheduling policy for kernel threads is determined by the operating system, and
+is often more inflexible than user-threads. Scheduling policy is said to be
+non-preemptive if a context-switch occurs only when the currently running
+thread willingly asks to be suspended, otherwise it is said to be preemptive.
+\jade threads are non-preemptive user-level threads.
+
+\item[Object] An object is just a blob of memory on which certain computations
+can be performed. The memory is referred to as an object's state, and the set
+of computations that can be performed on the object is called the interface of
+the object.
+
+\end{description}
+
+\section{\charmpp{}}
+
+\charmpp{} is an object-oriented parallel programming library for \CC{}.  It
+differs from traditional message passing programming libraries (such as MPI) in
+that \charmpp{} is ``message-driven''. Message-driven parallel programs do not
+block the processor waiting for a message to be received.  Instead, each
+message carries with itself a computation that the processor performs on
+arrival of that message. The underlying runtime system of \charmpp{} is called
+\converse{}, which implements a ``scheduler'' that chooses which message to
+schedule next (message-scheduling in \charmpp{} involves locating the object
+for which the message is intended, and executing the computation specified in
+the incoming message on that object). A parallel object in \charmpp{} is a
+\CC{} object on which a certain computations can be asked to performed from
+remote processors.
+
+\charmpp{} programs exhibit latency tolerance since the scheduler always picks
+up the next available message rather than waiting for a particular message to
+arrive.  They also tend to be modular, because of their object-based nature.
+Most importantly, \charmpp{} programs can be \emph{dynamically load balanced},
+because the messages are directed at objects and not at processors; thus
+allowing the runtime system to migrate the objects from heavily loaded
+processors to lightly loaded processors. It is this feature of \charmpp{} that
+we utilize for \jade.
+
+Since many CSE applications are originally written using MPI, one would have to
+do a complete rewrite if they were to be converted to \charmpp{} to take
+advantage of dynamic load balancing. This is indeed impractical. However,
+\converse{} -- the runtime system of \charmpp{} -- came to our rescue here,
+since it supports interoperability between different parallel programming
+paradigms such as parallel objects and threads. Using this feature, we
+developed \jade, an implementation of a significant subset of MPI-1.1
+standard over \charmpp{}.  \jade is described in the next section.
+
+\section{\jade}
+
+Every mainchare's main is executed at startup.
+
+\subsection{readonly}
+
+\begin{alltt}
+class C {
+    public static readonly CProxy_TheMain mainChare;
+    public static int readonly aReadOnly;
+}
+\end{alltt}
+
+Accessed as C.aReadOnly;
+
+Must be initialized in the main of a mainchare.  Value at the end of main is
+propagated to all processors.  Then execution begins.
+
+\subsection{msa}
+
+\begin{alltt}
+arr1.enroll();
+arr1[10] = 122; // set
+arr1[10] += 2;  // accumulate
+\end{alltt}
+
+\subsection{\jade Status}
+
+\subsection{Compiling \jade Programs}
+
+\charmpp{} provides a cross-platform compile-and-link script called \charmc{}
+to compile C, \CC{}, Fortran, \charmpp{} and \jade programs.  This script
+resides in the \texttt{bin} subdirectory in the \charmpp{} installation
+directory. The main purpose of this script is to deal with the differences of
+various compiler names and command-line options across various machines on
+which \charmpp{} runs. While, \charmc{} handles C and \CC{} compiler
+differences most of the time, the support for \jade is new, and may have
+bugs.
+
+In spite of the platform-neutral syntax of \charmc{}, one may have to specify
+some platform-specific options for compiling and building \jade codes.
+Fortunately, if \charmc{} does not recognize any particular options on its
+command line, it promptly passes it to all the individual compilers and linkers
+it invokes to compile the program.
+
+\appendix
+
+\section{Installing \jade}
+
+\jade is included in the source distribution of \charmpp{}. 
+To get the latest sources from PPL, visit:
+       http://charm.cs.uiuc.edu/
+
+and follow the download link.
+Now one has to build \charmpp{} and \jade from source.
+
+The build script for \charmpp{} is called \texttt{build}. The syntax for this
+script is:
+
+\begin{alltt}
+> build <target> <version> <opts>
+\end{alltt}
+
+For building \jade (which also includes building \charmpp{} and other
+libraries needed by \jade), specify \verb+<target>+ to be \verb+jade+. And
+\verb+<opts>+ are command line options passed to the \verb+charmc+ compile
+script.  Common compile time options such as \texttt{-g, -O, -Ipath, -Lpath,
+-llib} are accepted. 
+
+To build a debugging version of \jade, use the option: ``\texttt{-g}''. 
+To build a production version of \jade, use the options: ``\texttt{-O 
+-DCMK\_OPTIMIZE=1}''.
+
+\verb+<version>+ depends on the machine, operating system, and the underlying
+communication library one wants to use for running \jade programs.
+See the charm/README file for details on picking the proper version.
+Following is an example of how to build \jade under linux and ethernet
+environment, with debugging info produced:
+
+\begin{alltt}
+> build jade net-linux -g
+\end{alltt}
+
+\section{Building and Running \jade Programs}
+\subsection{Building}
+\charmpp{} provides a compiler called \charmc in your charm/bin/ directory. 
+You can use this compiler to build your \jade program the same way as other
+compilers like cc. Especially, to build an \jade program, a command line 
+option \emph{-language jade} should be applied. All the command line 
+flags that you would use for other compilers can be used with \charmc the 
+same way. For example:
+
+\begin{alltt}
+> charmc -language jade -c pgm.java -O3
+> charmc -language jade -o pgm pgm.o -lm -O3 
+\end{alltt}
+
+\subsection{Running}
+
+\charmpp{} distribution contains a script called \texttt{charmrun} that makes
+the job of running \jade programs portable and easier across all parallel
+machines supported by \charmpp{}. \texttt{charmrun} is copied to a directory
+where an \jade program is built using \charmc{}. It takes a command line
+parameter specifying number of processors, and the name of the program
+followed by \jade options (such as TBD) and the program arguments. A typical
+invocation of \jade program \texttt{pgm} with \texttt{charmrun} is:
+
+\begin{alltt}
+> charmrun pgm +p16 +vp32 +tcharm_stacksize 3276800
+\end{alltt}
+
+Here, the \jade program \texttt{pgm} is run on 16 physical processors with
+32 chunks (which will be mapped 2 per processor initially), where each
+user-level thread associated with a chunk has the stack size of 3,276,800 bytes.
+
+\section{Jade Developer documentation}
+
+\subsection{Files}
+
+\jade source files are spread out across several directories of the \charmpp{}
+CVS tree.
+\begin{tabular}{|r|l|}
+\hline\\
+charm/doc/jade                         & \jade user documentation files \\
+charm/src/langs/jade/                  & ANTLR parser files, \jade runtime library code\\
+charm/java/charm/jade/                 & \jade java code \\
+charm/java/bin/                        & \jade scripts \\
+charm/pgms/jade/                       & \jade example programs and tests \\
+\hline
+\end{tabular}
+
+After building \jade, files are installed in:
+\begin{tabular}{|r|l|}
+\hline\\
+charm/include/                         & \jade runtime library header files\\
+charm/lib/                             & \jade runtime library\\
+charm/java/bin/                        & \texttt{jade.jar} file \\
+\hline
+\end{tabular}
+
+\end{document}
diff --git a/src/langs/jade/JArray.C b/src/langs/jade/JArray.C
new file mode 100644 (file)
index 0000000..f9f30db
--- /dev/null
@@ -0,0 +1,2 @@
+// emacs mode line -*- mode: c++; tab-width: 4 -*-
+#include "JArray.h"
diff --git a/src/langs/jade/JArray.h b/src/langs/jade/JArray.h
new file mode 100644 (file)
index 0000000..9f8ee64
--- /dev/null
@@ -0,0 +1,355 @@
+// emacs mode line -*- mode: c++; tab-width: 4 -*-
+
+#ifndef JARRAY_H
+#define JARRAY_H
+
+#include <iostream>
+#include <assert.h>
+
+//for PUP::er
+#include <charm++.h>
+
+// for memcopy
+#include <string.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+#define DPRINT(a)
+
+typedef unsigned int uint;
+
+template<class T>
+class JArray {
+       uint numDimensions;
+       // e.g. a[10][20] dims = 10, 20  dimSize = 20, 1
+       uint *dims;              // array containing size of dim 1, 2, ...; 1-based
+       uint *dimSize;   // array containing num elements in dim 1, 2, ...; 1-based
+       T *data;
+
+       // virtual array to be used for next PUP
+       uint useVirtual;
+       uint *start;
+       uint *end;
+       uint *stride;
+
+public:
+       // Ways to set the dimension of the array:
+       // cons(dims)
+       // cons(), setDimension
+       // cons(), pup
+       // cons(), resize
+
+       // Constructor with dimensionality
+       JArray(const int numDims):dims(NULL), data(NULL), dimSize(NULL), useVirtual(0), start(NULL), end(NULL), stride(NULL)
+       {
+               //ckout << CkMyPe() << ": JArray(" << numDims << ") reached" << endl;
+               assert(numDims<=3); // @@ arbitrary limitation, code should work ok for larger dims
+               setDimension(numDims);
+       }
+
+       // Constructor without dimensionality
+       // something should be called immediately to set the dimensionality
+       JArray():numDimensions(0), dims(NULL), data(NULL), dimSize(NULL), useVirtual(0), start(NULL), end(NULL), stride(NULL)
+       {
+               //ckout << CkMyPe() << ": JArray() reached" << endl;
+       }
+
+       // Constructor from 1D C array
+       JArray(const int numElements, T *rawdata):numDimensions(0), dims(NULL), data(NULL), dimSize(NULL), useVirtual(0), start(NULL), end(NULL), stride(NULL)
+       {
+               //CkPrintf("DEBUG: %d %d %d\n", numElements, rawdata[0], rawdata[1]);
+               setDimension(1);
+               resize1D(numElements);
+               for(uint i=0; i<numElements; i++)
+                       data[i] = rawdata[i];
+       }
+
+       // Allocates dims and dimSize, but does not create the data array;
+       // resize or pup must be called.
+       void setDimension(uint numDims) {
+               //ckout << CkMyPe() << ": JArray::setDimension(" << numDims << ") reached" << endl;
+               numDimensions = numDims;
+               dims = new uint[numDimensions];
+               dimSize = new uint[numDimensions];
+               start = new uint[numDimensions];
+               end = new uint[numDimensions];
+               stride = new uint[numDimensions];
+               for(uint i=0; i<numDimensions; i++)
+                       dims[i] = dimSize[i] = start[i] = end[i] = stride[i] = 0;
+       }
+
+       // Copy constructor.  Needed for param marshalling.
+       // virtual array stuff is not copied
+       //
+       // Differs from copy assignment because cc deals with
+       // unallocated memory, but ca deals with a constructed object.
+       JArray(const JArray &rhs) {
+               int i = 0;
+
+               //CkPrintf("DEBUG: Copy constructor called\n");
+               setDimension(rhs.numDimensions);
+               //CkPrintf("DEBUG: CC: rhs.numDimensions = %d numDimensions = %d\n", rhs.numDimensions, numDimensions);
+               for(i=0; i<numDimensions; i++) {
+                       dims[i]=rhs.dims[i];
+                       dimSize[i]=rhs.dimSize[i];
+                       start[i] = end[i] = stride[i] = 0;
+               }
+               useVirtual=0;
+
+               //memcpy(dims, rhs.dims, numDimensions*sizeof(uint));
+               //CkPrintf("DEBUG: CC: rhs.dims[0] = %d, dims[0] = %d\n", rhs.dims[0], dims[0]);
+               //std::copy(dims, dims+numDimensions, rhs.dims);
+               //CkPrintf("DEBUG: CC: rhs.dims[0] = %d, dims[0] = %d\n", rhs.dims[0], dims[0]);
+               //memcpy(dimSize, rhs.dimSize, numDimensions*sizeof(uint));
+               //std::copy(dimSize, dimSize+numDimensions, rhs.dimSize);
+
+               int numElements = dims[0] * dimSize[0];
+               //         CkPrintf("DEBUG: CC: numElements = %d\n", numElements);
+               //         delete [] data;
+               data = new T[numElements];
+               //memcpy(data, rhs.data, numElements);
+               //std::copy(data, data+numElements, rhs.data);
+               for(i=0; i<numElements; i++)
+                       data[i] = rhs.data[i];
+               //         CkPrintf("DEBUG: CC: *data = %d *rhs.data = %d\n", *data, *rhs.data);
+       }
+
+       ~JArray() {
+               delete [] dims;
+               delete [] dimSize;
+               delete [] data;
+               delete [] start;
+               delete [] end;
+               delete [] stride;
+               dims = NULL;
+               dimSize = NULL;
+               data = NULL;
+               start = NULL;
+               end = NULL;
+               stride = NULL;
+       }
+
+       // resize populates dims and dimSize, and allocates the data array
+       // numDimensions may already be set, numDims is provided again just for verification.
+       // if numDimensions is not set, we set it to numDims.
+       //
+       // We do not allow resizing a JArray into a different number of
+       // dimensions.  We could, but will disallow it until I can think
+       // of a need for it.
+       JArray& resize(const uint numDims, const uint d[]){
+               //         ckout << CkMyPe() << ": JArray::resize(" << numDims << ".. reached" << endl;
+               int i;
+               if (numDimensions == 0)
+                       setDimension(numDims);
+               else
+                       assert(numDimensions==numDims);
+
+               uint dimSz = 1;
+               for(i=numDimensions-1; i>=0; i--) {
+                       dimSize[i] = dimSz;
+                       dimSz *= d[i];
+                       dims[i] = d[i];
+               }
+
+               uint numElements=dimSz;
+
+               //         cout << "DEBUG: " << numElements << " elements " << ", dimSize ";
+               //         for(i=0; i<numDimensions; i++)
+               //                 cout << dimSize[i] << " ";
+               //         cout << endl;
+
+               // resizing an already allocated array blows away the data.
+               if (data != NULL)
+                       delete [] data;
+               data = new T[numElements];
+
+               return *this;
+       }
+
+       // resize
+       JArray& resize1D(const uint d1){
+               uint d[] = { d1 };
+               return resize(1, d);
+       }
+
+       // resize
+       JArray& resize2D(const uint d1, const uint d2){
+               uint d[] = { d1, d2 };
+               return resize(2, d);
+       }
+
+       // resize
+       JArray& resize3D(const uint d1, const uint d2, const uint d3){
+               uint d[] = { d1, d2, d3 };
+               return resize(3, d);
+       }
+
+       // Get the size of the n'th dimension (1D, 2D ...)
+       int getDim(const uint n) {
+               assert(n>0 && n<=numDimensions);
+               return dims[n-1];
+       }
+
+       T* getBaseAddress() const { return data; }
+
+       //================================================================
+
+       // nD
+       // multi-dimensional JArray's.  a[b] where b is an array of
+       // the dimensions desired.
+       inline T& getElement(uint idx[]) {
+               uint index = 0;
+               for(uint i=0; i<numDimensions; i++) {
+                       assert(idx[i] >= 0 && idx[i] <= dims[i]);
+                       index += idx[i] * dimSize[i];
+               }
+               return data[index];
+       }
+       // multi-dimensional JArray's.  a[b] where b is an array of
+       // the dimensions desired.
+       //         inline T& operator[](uint i[]) {
+       //         T &tmp = getElement(i);
+       // //             CkPrintf("DEBUG: operator[[]] = %d *data=%d\n", tmp, *data);
+       //         return tmp;
+       //         }
+
+       // 1D
+       inline T& getElement(int i) {
+               uint idx[] = { i };
+               return getElement(idx);
+       }
+       inline T& operator () (int i0) {
+               return getElement(i0);
+       }
+       // a[10]
+       inline T& operator[](int i) {
+               //         uint idx[] = { i };
+               //         return (*this)[idx];
+               return getElement(i);
+       }
+
+       // 2D
+       inline T& getElement(int i, int j) {
+               uint idx[] = { i, j };
+               return getElement(idx);
+       }
+       inline T& operator () (int i0,int i1) {
+               return getElement(i0, i1);
+       }
+
+       // 3D
+       inline T& getElement(int i, int j, int k) {
+               uint idx[] = { i, j, k };
+               return getElement(idx);
+       }
+       inline T& operator () (int i0, int i1, int i2) {
+               return getElement(i0, i1, i2);
+       }
+
+       //         inline const T& operator[](int i) const;
+
+       // ================================================================
+
+       // 1D
+       // set Virtual Array
+       JArray& sV(uint s, uint e, uint str) {
+               assert(start != NULL);
+               assert(end != NULL);
+               assert(stride != NULL);
+               start[0] = s;
+               end[0] = e;
+               stride[0] = str;
+               useVirtual = 1;
+       }
+
+       // 2D
+       // set Virtual Array
+       JArray& sV(uint s, uint e, uint str,
+                          uint s1, uint e1, uint str1) {
+               sV(s, e, str);
+               assert(numDimensions >= 2);
+               start[1] = s1;
+               end[1] = e1;
+               stride[1] = str1;
+               return *this;
+       }
+       // 2D set Row
+       JArray& sR(uint row) {
+               sV(row, row, 1, 0, getDim(2)-1, 1);
+               return *this;
+       }
+       // 2D set Column
+       JArray& sC(uint col) {
+               sV(0, getDim(1)-1, 1, col, col, 1);
+               return *this;
+       }
+
+       void pupHelper(T *vdata, uint *vindex, uint *path, int depth) {
+               if (depth == numDimensions-1) {
+                       for(int i=start[depth]; i<=end[depth]; i+=stride[depth]) {
+                               path[depth] = i;
+                               vdata[*vindex] = getElement(path);
+                               (*vindex)++;
+                       }
+               } else {
+                       for(int i=start[depth]; i<=end[depth]; i+=stride[depth]) {
+                               path[depth] = i;
+                               pupHelper(vdata, vindex, path, depth+1);
+                       }
+               }
+       }
+
+       inline int ceiling(float f) {
+               int fi = (int)f;
+               return (f- fi)>=0.5 ? fi+1: fi;
+       }
+
+       virtual void pup(PUP::er &p){
+               // virtual case, and is packing or sizing
+               if (!p.isUnpacking() && useVirtual==1) {
+                       p|numDimensions;
+                       uint *vdims = new uint[numDimensions];
+                       uint *vdimSize = new uint[numDimensions];
+                       int i=0;
+                       for (i=0; i<numDimensions; i++)
+                               vdims[i] = ceiling( (end[i]-start[i]+1)/stride[i] );
+                       uint dimSz = 1;
+                       for(i=numDimensions-1; i>=0; i--) {
+                               vdimSize[i] = dimSz;
+                               dimSz *= vdims[i];
+                       }
+                       uint numElements=dimSz;
+                       p(vdims, numDimensions);
+                       p(vdimSize, numDimensions);
+                       T *vdata = new T[numElements];
+                       uint vindex = 0;
+                       uint *path = new uint[numDimensions];
+                       pupHelper(vdata, &vindex, path, 0);
+                       p(vdata, numElements);
+                       if (p.isPacking()) useVirtual=0;
+                       delete [] vdims;
+                       delete [] vdimSize;
+                       delete [] vdata;
+                       delete [] path;
+               } else {// virtual case unpacking, or normal case pup
+                       p|numDimensions;
+                       if (p.isUnpacking()) {
+                               //                 dims = new uint[numDimensions];
+                               //                 dimSize = new uint[numDimensions];
+                               setDimension(numDimensions);
+                       }
+                       p(dims, numDimensions);
+                       p(dimSize, numDimensions);
+                       int numElements = dims[0] * dimSize[0];
+                       if (p.isUnpacking()) {
+                               data = new T[numElements];
+                       }
+                       p(data, numElements);
+               }
+       }
+
+};
+
+#endif
+// JARRAY_H
diff --git a/src/langs/jade/Makefile b/src/langs/jade/Makefile
new file mode 100644 (file)
index 0000000..fb35321
--- /dev/null
@@ -0,0 +1,81 @@
+# Compiles libjade.a and puts it into place
+# Compiles *.g files, which requires ANTLR
+#  Puts resulting .java files into place in charm/java/charm/jade/
+
+CDIR=../../..
+#Antlr jar files needed for jade user
+AUDIR = $(CDIR)/bin/charmjavabin/antlr.jar
+#Antlr jar files needed for jade developer
+ADDIR = $(CDIR)/bin/charmjavabin/antlralld.jar
+
+CHARMC=$(CDIR)/bin/charmc $(OPTS)
+CP=/bin/cp
+MV=/bin/mv
+
+LIB = libjade.a
+LIBOBJ = JArray.o
+HEADERS = JArray.h jade.h
+LIBDEST =  $(CDIR)/lib/
+
+JAVADEST = $(CDIR)/java/charm/jade
+
+all: c l
+
+all2: c l p
+
+default:
+       @echo "Specify target: l(ib) p(arsers) c(clean)"
+
+clean: cleanlib cleanparsers
+
+l: lib
+
+c: clean
+
+p: parsers
+
+#================================================================
+lib: $(LIBDEST)
+
+$(LIBDEST) : cleanlib $(LIB)
+       $(MV) $(LIB) $(LIBDEST)
+       $(CP) $(HEADERS) $(CDIR)/include
+
+$(LIB): $(LIBOBJ)
+       $(CHARMC) -o $(LIB) $(LIBOBJ) 
+
+JArray.o: JArray.h JArray.C
+       $(CHARMC) -c JArray.C
+
+cleanlib:
+       rm -f *.o $(LIB)
+
+#================================================================
+
+parsers: cleanparsers t0 t1 t2
+
+#Call Antlr to compile a .g file
+Antlr = java -classpath $(ADDIR) antlr.Tool
+
+#The Java parser
+t0:
+       $(Antlr) java.g
+       $(CP) JavaRecognizer.java JavaTokenTypes.java JavaLexer.java $(JAVADEST)
+#      $(javacA) JavaRecognizer.java JavaTokenTypes.java JavaLexer.java
+
+#The first pass tree parser
+t1:
+       $(Antlr) java.tree1.g
+       $(CP) JavaTreeParser1.java JavaTreeParser1TokenTypes.java $(JAVADEST)
+#      $(javacA) JavaTreeParser1.java JavaTreeParser1TokenTypes.java
+
+#The second pass tree parser
+t2:
+       $(Antlr) java.tree.g
+       $(CP) JavaTreeParser.java JavaTreeParserTokenTypes.java $(JAVADEST)
+#      $(javacA) JavaTreeParser.java JavaTreeParserTokenTypes.java
+
+cleanparsers:
+       rm -f JavaLexer.java JavaTokenTypes.java JavaTokenTypes.txt JavaRecognizer.java
+       rm -f JavaTreeParser1.java JavaTreeParser1TokenTypes.java JavaTreeParser1TokenTypes.txt
+       rm -f JavaTreeParser.java JavaTreeParserTokenTypes.java JavaTreeParserTokenTypes.txt
diff --git a/src/langs/jade/jade.h b/src/langs/jade/jade.h
new file mode 100644 (file)
index 0000000..8c93ccd
--- /dev/null
@@ -0,0 +1,8 @@
+// emacs mode line -*- mode: c++; tab-width: 4 -*-
+#ifndef JADE_H
+#define JADE_H
+
+#include "JArray.h"
+#include "msa/msa.h"
+
+#endif
diff --git a/src/langs/jade/java.g b/src/langs/jade/java.g
new file mode 100644 (file)
index 0000000..27e3bfc
--- /dev/null
@@ -0,0 +1,1256 @@
+{
+import JJ.*;
+}
+
+/** Java 1.3 Recognizer
+ *
+ * Run 'java Main [-showtree] directory-full-of-java-files'
+ *
+ * [The -showtree option pops up a Swing frame that shows
+ *  the AST constructed from the parser.]
+ * 
+ * Run 'java Main <directory full of java files>'
+ *
+ * Contributing authors:
+ *             John Mitchell           johnm@non.net
+ *             Terence Parr            parrt@magelang.com
+ *             John Lilley                     jlilley@empathy.com
+ *             Scott Stanchfield       thetick@magelang.com
+ *             Markus Mohnen       mohnen@informatik.rwth-aachen.de
+ *      Peter Williams      pete.williams@sun.com
+ *      Allan Jacobs        Allan.Jacobs@eng.sun.com
+ *      Steve Messick       messick@redhills.com
+ *
+ * Version 1.00 December 9, 1997 -- initial release
+ * Version 1.01 December 10, 1997
+ *             fixed bug in octal def (0..7 not 0..8)
+ * Version 1.10 August 1998 (parrt)
+ *             added tree construction
+ *             fixed definition of WS,comments for mac,pc,unix newlines
+ *             added unary plus
+ * Version 1.11 (Nov 20, 1998)
+ *             Added "shutup" option to turn off last ambig warning.
+ *             Fixed inner class def to allow named class defs as statements
+ *             synchronized requires compound not simple statement
+ *             add [] after builtInType DOT class in primaryExpression
+ *             "const" is reserved but not valid..removed from modifiers
+ * Version 1.12 (Feb 2, 1999)
+ *             Changed LITERAL_xxx to xxx in tree grammar.
+ *             Updated java.g to use tokens {...} now for 2.6.0 (new feature).
+ *
+ * Version 1.13 (Apr 23, 1999)
+ *             Didn't have (stat)? for else clause in tree parser.
+ *             Didn't gen ASTs for interface extends.  Updated tree parser too.
+ *             Updated to 2.6.0.
+ * Version 1.14 (Jun 20, 1999)
+ *             Allowed final/abstract on local classes.
+ *             Removed local interfaces from methods
+ *             Put instanceof precedence where it belongs...in relationalExpr
+ *                     It also had expr not type as arg; fixed it.
+ *             Missing ! on SEMI in classBlock
+ *             fixed: (expr) + "string" was parsed incorrectly (+ as unary plus).
+ *             fixed: didn't like Object[].class in parser or tree parser
+ * Version 1.15 (Jun 26, 1999)
+ *             Screwed up rule with instanceof in it. :(  Fixed.
+ *             Tree parser didn't like (expr).something; fixed.
+ *             Allowed multiple inheritance in tree grammar. oops.
+ * Version 1.16 (August 22, 1999)
+ *             Extending an interface built a wacky tree: had extra EXTENDS.
+ *             Tree grammar didn't allow multiple superinterfaces.
+ *             Tree grammar didn't allow empty var initializer: {}
+ * Version 1.17 (October 12, 1999)
+ *             ESC lexer rule allowed 399 max not 377 max.
+ *             java.tree.g didn't handle the expression of synchronized
+ *             statements.
+ * Version 1.18 (August 12, 2001)
+ *      Terence updated to Java 2 Version 1.3 by observing/combining work of
+ *      Allan Jacobs and Steve Messick.  Handles 1.3 src.
+ *             Summary:
+ *             o  primary didn't include boolean.class kind of thing
+ *      o  constructor calls parsed explicitly now:
+ *                see explicitConstructorInvocation
+ *             o  add strictfp modifier
+ *      o  missing objBlock after new expression in tree grammar
+ *             o  merged local class definition alternatives, moved after declaration
+ *             o  fixed problem with ClassName.super.field
+ *      o  reordered some alternatives to make things more efficient
+ *             o  long and double constants were not differentiated from int/float
+ *             o  whitespace rule was inefficient: matched only one char
+ *             o  add an examples directory with some nasty 1.3 cases
+ *             o  made Main.java use buffered IO and a Reader for Unicode support
+ *             o  supports UNICODE?
+ *                Using Unicode charVocabulay makes code file big, but only
+ *                in the bitsets at the end. I need to make ANTLR generate
+ *                unicode bitsets more efficiently.
+ *
+ * class Test {
+ *   public static void main( String args[] ) {
+ *     if (boolean.class.equals(boolean.class)) {
+ *       System.out.println("works");
+ *     }
+ *   }
+ * }
+ *
+ * This grammar is in the PUBLIC DOMAIN
+ */
+class JavaRecognizer extends Parser;
+options {
+       k = 2;                           // two token lookahead
+       exportVocab=Java;                // Call its vocabulary "Java"
+       codeGenMakeSwitchThreshold = 2;  // Some optimizations
+       codeGenBitsetTestThreshold = 3;
+       defaultErrorHandler = false;     // Don't generate parser error handlers
+       buildAST = true;
+}
+
+tokens {
+       BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; 
+       INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; 
+       PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE;
+       PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; 
+       POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; 
+       IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; 
+       FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
+       STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; TEMPLATE;
+}
+       
+// Compilation Unit: In Java, this is a single file.  This is the start
+//   rule for this parser
+compilationUnit
+       :       // A compilation unit starts with an optional package definition
+               (       packageDefinition
+               |       /* nothing */
+               )
+
+               // Next we have a series of zero or more import statements
+               ( importDefinition )*
+
+               // Wrapping things up with any number of class or interface
+               //    definitions
+               ( typeDefinition )*
+
+               EOF!
+       ;
+
+
+// Package statement: "package" followed by an identifier.
+packageDefinition
+       options {defaultErrorHandler = true;} // let ANTLR handle errors
+       :       p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI!
+       ;
+
+
+// Import statement: import followed by a package or class name
+importDefinition
+       options {defaultErrorHandler = true;}
+       :       i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI!
+       ;
+
+// A type definition in a file is either a class or interface definition.
+typeDefinition
+       options {defaultErrorHandler = true;}
+       :       m:modifiers!
+               ( classDefinition[#m]
+               | interfaceDefinition[#m]
+               )
+       |       SEMI!
+       ;
+
+/** A declaration is the creation of a reference or primitive-type variable
+ *  Create a separate Type/Var tree for each var in the var list.
+ */
+declaration!
+       :       m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t]
+               {#declaration = #v;}
+       ;
+
+// A type specification is a type name with possible brackets afterwards
+//   (which would make it an array type).
+typeSpec[boolean addImagNode]
+       : classTypeSpec[addImagNode]
+       | builtInTypeSpec[addImagNode]
+       ;
+
+// A class type specification is a class type with possible brackets afterwards
+//   (which would make it an array type).
+classTypeSpec[boolean addImagNode]
+       :       identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+               {
+                       if ( addImagNode ) {
+                               #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec);
+                       }
+               }
+//         | identifier lt:LT^ {#lt.setType(TEMPLATE);} GT!
+//             {
+//                     if ( addImagNode ) {
+//                             #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec);
+//                     }
+//             }
+       ;
+
+// A builtin type specification is a builtin type with possible brackets
+// afterwards (which would make it an array type).
+builtInTypeSpec[boolean addImagNode]
+       :       builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+               {
+                       if ( addImagNode ) {
+                               #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec);
+                       }
+               }
+       ;
+
+// A type name. which is either a (possibly qualified) class name or
+//   a primitive (builtin) type
+type
+       :       identifier
+       |       builtInType
+       ;
+
+// The primitive types.
+builtInType
+       :       "void"
+       |       "boolean"
+       |       "byte"
+       |       "char"
+       |       "short"
+       |       "int"
+       |       "float"
+       |       "long"
+       |       "double"
+       ;
+
+templater
+    :    ( lt:LT^ {#lt.setType(TEMPLATE);} identifier ( COMMA! identifier )* GT! )
+    ;
+
+// A (possibly-qualified) java identifier.  We start with the first IDENT
+//   and expand its name by adding dots and following IDENTS
+identifier
+       :       IDENT^  ( DOT^ IDENT )* ( templater )?
+       ;
+
+identifierStar
+       :       IDENT
+               ( DOT^ IDENT )*
+               ( DOT^ STAR  )?
+       ;
+
+// A list of zero or more modifiers.  We could have used (modifier)* in
+//   place of a call to modifiers, but I thought it was a good idea to keep
+//   this rule separate so they can easily be collected in a Vector if
+//   someone so desires
+modifiers
+       :       ( modifier )*
+               {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);}
+       ;
+
+// modifiers for Java classes, interfaces, class/instance vars and methods
+modifier
+       :       "private"
+       |       "public"
+       |       "protected"
+       |       "static"
+       |       "transient"
+       |       "final"
+       |       "abstract"
+       |       "native"
+       |       "threadsafe"
+       |       "synchronized"
+//     |       "const"                 // reserved word, but not valid
+       |       "volatile"
+       |       "strictfp"
+       |       "threaded"
+       |       "sync"
+       |       "readonly"
+       ;
+
+// Definition of a Java class
+classDefinition![AST modifiers]
+       :       "class" IDENT
+               // it _might_ have a superclass...
+               sc:superClassClause
+               // it might implement some interfaces...
+               ic:implementsClause
+               // now parse the body of the class
+               cb:classBlock
+//             {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"],
+//                                                        modifiers,IDENT,sc,ic,cb);}
+               { AST t = new ClassNode(); t.setType(CLASS_DEF); t.setText("CLASS_DEF");
+            #classDefinition = #(t,
+                                                          modifiers,IDENT,sc,ic,cb);}
+       ;
+
+superClassClause!
+       :       ( "extends" id:identifier )?
+               {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);}
+       ;
+
+// Definition of a Java Interface
+interfaceDefinition![AST modifiers]
+       :       "interface" IDENT
+               // it might extend some other interfaces
+               ie:interfaceExtends
+               // now parse the body of the interface (looks like a class...)
+               cb:classBlock
+               {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"],
+                                                                       modifiers,IDENT,ie,cb);}
+       ;
+
+
+// This is the body of a class.  You can have fields and extra semicolons,
+// That's about it (until you see what a field is...)
+classBlock
+       :       LCURLY!
+                       ( field | SEMI! )*
+               RCURLY!
+               {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);}
+       ;
+
+// An interface can extend several other interfaces...
+interfaceExtends
+       :       (
+               e:"extends"!
+               identifier ( COMMA! identifier )*
+               )?
+               {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],
+                                                       #interfaceExtends);}
+       ;
+
+// A class can implement several interfaces...
+implementsClause
+       :       (
+                       i:"implements"! identifier ( COMMA! identifier )*
+               )?
+               {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"],
+                                                                #implementsClause);}
+       ;
+
+// Now the various things that can be defined inside a class or interface...
+// Note that not all of these are really valid in an interface (constructors,
+//   for example), and if this grammar were used for a compiler there would
+//   need to be some semantic checks to make sure we're doing the right thing...
+field!
+       :       // method, constructor, or variable declaration
+               mods:modifiers
+               (       h:ctorHead s:constructorBody // constructor
+                       {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);}
+
+               |       cd:classDefinition[#mods]       // inner class
+                       {#field = #cd;}
+                       
+               |       id:interfaceDefinition[#mods]   // inner interface
+                       {#field = #id;}
+
+               |       t:typeSpec[false]  // method or variable declaration(s)
+                       (       IDENT  // the name of the method
+
+                               // parse the formal parameter declarations.
+                               LPAREN! param:parameterDeclarationList RPAREN!
+
+                               rt:declaratorBrackets[#t]
+
+                               // get the list of exceptions that this method is
+                               // declared to throw
+                               (tc:throwsClause)?
+
+                               ( s2:compoundStatement | SEMI )
+                               {#field = #(#[METHOD_DEF,"METHOD_DEF"],
+                                                    mods,
+                                                        #(#[TYPE,"TYPE"],rt),
+                                                        IDENT,
+                                                        param,
+                                                        tc,
+                                                        s2);}
+                       |       v:variableDefinitions[#mods,#t] SEMI
+//                             {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);}
+                               {#field = #v;}
+                       )
+               )
+
+    // "static { ... }" class initializer
+       |       "static" s3:compoundStatement
+               {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);}
+
+    // "{ ... }" instance initializer
+       |       s4:compoundStatement
+               {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);}
+       ;
+
+constructorBody
+    :   lc:LCURLY^ {#lc.setType(SLIST);}
+               // Predicate might be slow but only checked once per constructor def
+               // not for general methods.
+               (       (explicitConstructorInvocation) => explicitConstructorInvocation
+               |
+               )
+        (statement)*
+        RCURLY!
+    ;
+
+explicitConstructorInvocation
+    :   (      options {
+                               // this/super can begin a primaryExpression too; with finite
+                               // lookahead ANTLR will think the 3rd alternative conflicts
+                               // with 1, 2.  I am shutting off warning since ANTLR resolves
+                               // the nondeterminism by correctly matching alts 1 or 2 when
+                               // it sees this( or super(
+                               generateAmbigWarnings=false;
+                       }
+               :       "this"! lp1:LPAREN^ argList RPAREN! SEMI!
+                       {#lp1.setType(CTOR_CALL);}
+
+           |   "super"! lp2:LPAREN^ argList RPAREN! SEMI!
+                       {#lp2.setType(SUPER_CTOR_CALL);}
+
+                       // (new Outer()).super()  (create enclosing instance)
+               |       primaryExpression DOT! "super"! lp3:LPAREN^ argList RPAREN! SEMI!
+                       {#lp3.setType(SUPER_CTOR_CALL);}
+               )
+    ;
+
+variableDefinitions[AST mods, AST t]
+       :       variableDeclarator[getASTFactory().dupTree(mods),
+                                                  getASTFactory().dupTree(t)]
+               (       COMMA!
+                       variableDeclarator[getASTFactory().dupTree(mods),
+                                                          getASTFactory().dupTree(t)]
+               )*
+       ;
+
+/** Declaration of a variable.  This can be a class/instance variable,
+ *   or a local variable in a method
+ * It can also include possible initialization.
+ */
+variableDeclarator![AST mods, AST t]
+       :       id:IDENT d:declaratorBrackets[t] v:varInitializer
+               {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v);}
+       ;
+
+declaratorBrackets[AST typ]
+       :       {#declaratorBrackets=typ;}
+               (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+       ;
+
+varInitializer
+       :       ( ASSIGN^ initializer )?
+       ;
+
+// This is an initializer used to set up an array.
+arrayInitializer
+       :       lc:LCURLY^ {#lc.setType(ARRAY_INIT);}
+                       (       initializer
+                               (
+                                       // CONFLICT: does a COMMA after an initializer start a new
+                                       //           initializer or start the option ',' at end?
+                                       //           ANTLR generates proper code by matching
+                                       //                       the comma as soon as possible.
+                                       options {
+                                               warnWhenFollowAmbig = false;
+                                       }
+                               :
+                                       COMMA! initializer
+                               )*
+                               (COMMA!)?
+                       )?
+               RCURLY!
+       ;
+
+
+// The two "things" that can initialize an array element are an expression
+//   and another (nested) array initializer.
+initializer
+       :       expression
+       |       arrayInitializer
+       ;
+
+// This is the header of a method.  It includes the name and parameters
+//   for the method.
+//   This also watches for a list of exception classes in a "throws" clause.
+ctorHead
+       :       IDENT  // the name of the method
+
+               // parse the formal parameter declarations.
+               LPAREN! parameterDeclarationList RPAREN!
+
+               // get the list of exceptions that this method is declared to throw
+               (throwsClause)?
+       ;
+
+// This is a list of exception classes that the method is declared to throw
+throwsClause
+       :       "throws"^ identifier ( COMMA! identifier )*
+       ;
+
+
+// A list of formal parameters
+parameterDeclarationList
+       :       ( parameterDeclaration ( COMMA! parameterDeclaration )* )?
+               {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"],
+                                                                       #parameterDeclarationList);}
+       ;
+
+// A formal parameter.
+parameterDeclaration!
+       :       pm:parameterModifier t:typeSpec[false] id:IDENT
+               pd:declaratorBrackets[#t]
+               {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"],
+                                                                       pm, #([TYPE,"TYPE"],pd), id);}
+       ;
+
+parameterModifier
+       :       (f:"final")?
+               {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);}
+       ;
+
+// Compound statement.  This is used in many contexts:
+//   Inside a class definition prefixed with "static":
+//      it is a class initializer
+//   Inside a class definition without "static":
+//      it is an instance initializer
+//   As the body of a method
+//   As a completely indepdent braced block of code inside a method
+//      it starts a new scope for variable definitions
+
+compoundStatement
+       :       lc:LCURLY^ {#lc.setType(SLIST);}
+                       // include the (possibly-empty) list of statements
+                       (statement)*
+               RCURLY!
+       ;
+
+
+statement
+       // A list of statements in curly braces -- start a new scope!
+       :       compoundStatement
+
+       // declarations are ambiguous with "ID DOT" relative to expression
+       // statements.  Must backtrack to be sure.  Could use a semantic
+       // predicate to test symbol table to see what the type was coming
+       // up, but that's pretty hard without a symbol table ;)
+       |       (declaration)=> declaration SEMI!
+
+       // An expression statement.  This could be a method call,
+       // assignment statement, or any other expression evaluated for
+       // side-effects.
+       |       expression SEMI!
+
+       // class definition
+       |       m:modifiers! classDefinition[#m]
+
+       // Attach a label to the front of a statement
+       |       IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement
+
+       // If-else statement
+       |       "if"^ LPAREN! expression RPAREN! statement
+               (
+                       // CONFLICT: the old "dangling-else" problem...
+                       //           ANTLR generates proper code matching
+                       //                       as soon as possible.  Hush warning.
+                       options {
+                               warnWhenFollowAmbig = false;
+                       }
+               :
+                       "else"! statement
+               )?
+
+       // For statement
+       |       "for"^
+                       LPAREN!
+                               forInit SEMI!   // initializer
+                               forCond SEMI!   // condition test
+                               forIter         // updater
+                       RPAREN!
+                       statement                     // statement to loop over
+
+       // While statement
+       |       "while"^ LPAREN! expression RPAREN! statement
+
+       // do-while statement
+       |       "do"^ statement "while"! LPAREN! expression RPAREN! SEMI!
+
+       // get out of a loop (or switch)
+       |       "break"^ (IDENT)? SEMI!
+
+       // do next iteration of a loop
+       |       "continue"^ (IDENT)? SEMI!
+
+       // Return an expression
+       |       "return"^ (expression)? SEMI!
+
+       // switch/case statement
+       |       "switch"^ LPAREN! expression RPAREN! LCURLY!
+                       ( casesGroup )*
+               RCURLY!
+
+       // exception try-catch block
+       |       tryBlock
+
+       // throw an exception
+       |       "throw"^ expression SEMI!
+
+       // synchronize a statement
+       |       "synchronized"^ LPAREN! expression RPAREN! compoundStatement
+
+       // empty statement
+       |       s:SEMI {#s.setType(EMPTY_STAT);}
+       ;
+
+
+casesGroup
+       :       (       // CONFLICT: to which case group do the statements bind?
+                       //           ANTLR generates proper code: it groups the
+                       //           many "case"/"default" labels together then
+                       //           follows them with the statements
+                       options {
+                               warnWhenFollowAmbig = false;
+                       }
+                       :
+                       aCase
+               )+
+               caseSList
+               {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);}
+       ;
+
+aCase
+       :       ("case"^ expression | "default") COLON!
+       ;
+
+caseSList
+       :       (statement)*
+               {#caseSList = #(#[SLIST,"SLIST"],#caseSList);}
+       ;
+
+// The initializer for a for loop
+forInit
+               // if it looks like a declaration, it is
+       :       (       (declaration)=> declaration
+               // otherwise it could be an expression list...
+               |       expressionList
+               )?
+               {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);}
+       ;
+
+forCond
+       :       (expression)?
+               {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);}
+       ;
+
+forIter
+       :       (expressionList)?
+               {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);}
+       ;
+
+// an exception handler try/catch block
+tryBlock
+       :       "try"^ compoundStatement
+               (handler)*
+               ( "finally"^ compoundStatement )?
+       ;
+
+
+// an exception handler
+handler
+       :       "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement
+       ;
+
+
+// expressions
+// Note that most of these expressions follow the pattern
+//   thisLevelExpression :
+//       nextHigherPrecedenceExpression
+//           (OPERATOR nextHigherPrecedenceExpression)*
+// which is a standard recursive definition for a parsing an expression.
+// The operators in java have the following precedences:
+//    lowest  (13)  = *= /= %= += -= <<= >>= >>>= &= ^= |=
+//            (12)  ?:
+//            (11)  ||
+//            (10)  &&
+//            ( 9)  |
+//            ( 8)  ^
+//            ( 7)  &
+//            ( 6)  == !=
+//            ( 5)  < <= > >=
+//            ( 4)  << >>
+//            ( 3)  +(binary) -(binary)
+//            ( 2)  * / %
+//            ( 1)  ++ -- +(unary) -(unary)  ~  !  (type)
+//                  []   () (method call)  . (dot -- identifier qualification)
+//                  new   ()  (explicit parenthesis)
+//
+// the last two are not usually on a precedence chart; I put them in
+// to point out that new has a higher precedence than '.', so you
+// can validy use
+//     new Frame().show()
+// 
+// Note that the above precedence levels map to the rules below...
+// Once you have a precedence chart, writing the appropriate rules as below
+//   is usually very straightfoward
+
+
+
+// the mother of all expressions
+expression
+       :       assignmentExpression
+               {#expression = #(#[EXPR,"EXPR"],#expression);}
+       ;
+
+
+// This is a list of expressions.
+expressionList
+       :       expression (COMMA! expression)*
+               {#expressionList = #(#[ELIST,"ELIST"], expressionList);}
+       ;
+
+
+// assignment expression (level 13)
+assignmentExpression
+       :       conditionalExpression
+               (       (       ASSIGN^
+            |   PLUS_ASSIGN^
+            |   MINUS_ASSIGN^
+            |   STAR_ASSIGN^
+            |   DIV_ASSIGN^
+            |   MOD_ASSIGN^
+            |   SR_ASSIGN^
+            |   BSR_ASSIGN^
+            |   SL_ASSIGN^
+            |   BAND_ASSIGN^
+            |   BXOR_ASSIGN^
+            |   BOR_ASSIGN^
+            )
+                       assignmentExpression
+               )?
+       ;
+
+
+// conditional test (level 12)
+conditionalExpression
+       :       logicalOrExpression
+               ( QUESTION^ assignmentExpression COLON! conditionalExpression )?
+       ;
+
+
+// logical or (||)  (level 11)
+logicalOrExpression
+       :       logicalAndExpression (LOR^ logicalAndExpression)*
+       ;
+
+
+// logical and (&&)  (level 10)
+logicalAndExpression
+       :       inclusiveOrExpression (LAND^ inclusiveOrExpression)*
+       ;
+
+
+// bitwise or non-short-circuiting or (|)  (level 9)
+inclusiveOrExpression
+       :       exclusiveOrExpression (BOR^ exclusiveOrExpression)*
+       ;
+
+
+// exclusive or (^)  (level 8)
+exclusiveOrExpression
+       :       andExpression (BXOR^ andExpression)*
+       ;
+
+
+// bitwise or non-short-circuiting and (&)  (level 7)
+andExpression
+       :       equalityExpression (BAND^ equalityExpression)*
+       ;
+
+
+// equality/inequality (==/!=) (level 6)
+equalityExpression
+       :       relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)*
+       ;
+
+
+// boolean relational expressions (level 5)
+relationalExpression
+       :       shiftExpression
+               (       (       (       LT^
+                               |       GT^
+                               |       LE^
+                               |       GE^
+                               )
+                               shiftExpression
+                       )*
+               |       "instanceof"^ typeSpec[true]
+               )
+       ;
+
+
+// colon expression for array sections
+colonExpression
+    :   expression (COLON^ expression (COLON! expression)?)?
+    ;
+
+
+// bit shift expressions (level 4)
+shiftExpression
+       :       additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)*
+       ;
+
+
+// binary addition/subtraction (level 3)
+additiveExpression
+       :       multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
+       ;
+
+
+// multiplication/division/modulo (level 2)
+multiplicativeExpression
+       :       unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
+       ;
+
+unaryExpression
+       :       INC^ unaryExpression
+       |       DEC^ unaryExpression
+       |       MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
+       |       PLUS^  {#PLUS.setType(UNARY_PLUS);} unaryExpression
+       |       unaryExpressionNotPlusMinus
+       ;
+
+unaryExpressionNotPlusMinus
+       :       BNOT^ unaryExpression
+       |       LNOT^ unaryExpression
+
+       |       (       // subrule allows option to shut off warnings
+                       options {
+                               // "(int" ambig with postfixExpr due to lack of sequence
+                               // info in linear approximate LL(k).  It's ok.  Shut up.
+                               generateAmbigWarnings=false;
+                       }
+               :       // If typecast is built in type, must be numeric operand
+                       // Also, no reason to backtrack if type keyword like int, float...
+                       lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN!
+                       unaryExpression
+
+                       // Have to backtrack to see if operator follows.  If no operator
+                       // follows, it's a typecast.  No semantic checking needed to parse.
+                       // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)"
+               |       (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=>
+                       lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN!
+                       unaryExpressionNotPlusMinus
+
+               |       postfixExpression
+               )
+       ;
+
+// qualified names, array expressions, method invocation, post inc/dec
+postfixExpression
+       :       primaryExpression // start with a primary
+
+               (       // qualified id (id.id.id.id...) -- build the name
+                       DOT^ ( IDENT
+                               | "this"
+                               | "class"
+                               | newExpression
+                               | "super" // ClassName.super.field
+                               )
+                       // the above line needs a semantic check to make sure "class"
+                       // is the _last_ qualifier.
+
+                       // allow ClassName[].class
+               |       ( lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+
+                       DOT^ "class"
+
+                       // an array indexing operation
+//             |       lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK!
+               |       lb1:LBRACK^ {#lb1.setType(INDEX_OP);} colonExpression RBRACK!
+
+                       // method invocation
+                       // The next line is not strictly proper; it allows x(3)(4) or
+                       //  x[2](4) which are not valid in Java.  If this grammar were used
+                       //  to validate a Java program a semantic check would be needed, or
+                       //   this rule would get really ugly...
+                       // It also allows ctor invocation like super(3) which is now
+                       // handled by the explicit constructor rule, but it would
+                       // be hard to syntactically prevent ctor calls here
+               |       lp:LPAREN^ {#lp.setType(METHOD_CALL);}
+                               argList
+                       RPAREN!
+               )*
+
+               // possibly add on a post-increment or post-decrement.
+               // allows INC/DEC on too much, but semantics can check
+               (       in:INC^ {#in.setType(POST_INC);}
+               |       de:DEC^ {#de.setType(POST_DEC);}
+               |       // nothing
+               )
+       ;
+
+// the basic element of an expression
+primaryExpression
+       :       IDENT
+       |       constant
+       |       "true"
+       |       "false"
+       |       "this"
+       |       "null"
+       |       newExpression
+       |       LPAREN! assignmentExpression RPAREN!
+       |       "super"
+               // look for int.class and int[].class
+       |       builtInType 
+               ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )*
+               DOT^ "class"
+       ;
+
+/** object instantiation.
+ *  Trees are built as illustrated by the following input/tree pairs:
+ *  
+ *  new T()
+ *  
+ *  new
+ *   |
+ *   T --  ELIST
+ *           |
+ *          arg1 -- arg2 -- .. -- argn
+ *  
+ *  new int[]
+ *
+ *  new
+ *   |
+ *  int -- ARRAY_DECLARATOR
+ *  
+ *  new int[] {1,2}
+ *
+ *  new
+ *   |
+ *  int -- ARRAY_DECLARATOR -- ARRAY_INIT
+ *                                  |
+ *                                EXPR -- EXPR
+ *                                  |      |
+ *                                  1      2
+ *  
+ *  new int[3]
+ *  new
+ *   |
+ *  int -- ARRAY_DECLARATOR
+ *                |
+ *              EXPR
+ *                |
+ *                3
+ *  
+ *  new int[1][2]
+ *  
+ *  new
+ *   |
+ *  int -- ARRAY_DECLARATOR
+ *               |
+ *         ARRAY_DECLARATOR -- EXPR
+ *               |              |
+ *             EXPR             1
+ *               |
+ *               2
+ *  
+ */
+newExpression
+       :       "new"^ type
+               (       LPAREN! argList RPAREN! (classBlock)?
+
+                       //java 1.1
+                       // Note: This will allow bad constructs like
+                       //    new int[4][][3] {exp,exp}.
+                       //    There needs to be a semantic check here...
+                       // to make sure:
+                       //   a) [ expr ] and [ ] are not mixed
+                       //   b) [ expr ] and an init are not used together
+
+               |       newArrayDeclarator (arrayInitializer)?
+               )
+       ;
+
+argList
+       :       (       expressionList
+               |       /*nothing*/
+                       {#argList = #[ELIST,"ELIST"];}
+               )
+       ;
+
+newArrayDeclarator
+       :       (
+                       // CONFLICT:
+                       // newExpression is a primaryExpression which can be
+                       // followed by an array index reference.  This is ok,
+                       // as the generated code will stay in this loop as
+                       // long as it sees an LBRACK (proper behavior)
+                       options {
+                               warnWhenFollowAmbig = false;
+                       }
+               :
+                       lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);}
+                               (expression)?
+                       RBRACK!
+               )+
+       ;
+
+constant
+       :       NUM_INT
+       |       CHAR_LITERAL
+       |       STRING_LITERAL
+       |       NUM_FLOAT
+       |       NUM_LONG
+       |       NUM_DOUBLE
+       ;
+
+
+//----------------------------------------------------------------------------
+// The Java scanner
+//----------------------------------------------------------------------------
+class JavaLexer extends Lexer;
+
+options {
+       exportVocab=Java;      // call the vocabulary "Java"
+       testLiterals=false;    // don't automatically test for literals
+       k=4;                   // four characters of lookahead
+       charVocabulary='\u0003'..'\uFFFF';
+       // without inlining some bitset tests, couldn't do unicode;
+       // I need to make ANTLR generate smaller bitsets; see
+       // bottom of JavaLexer.java
+       codeGenBitsetTestThreshold=20;
+}
+
+
+
+// OPERATORS
+QUESTION               :       '?'             ;
+LPAREN                 :       '('             ;
+RPAREN                 :       ')'             ;
+LBRACK                 :       '['             ;
+RBRACK                 :       ']'             ;
+LCURLY                 :       '{'             ;
+RCURLY                 :       '}'             ;
+COLON                  :       ':'             ;
+COMMA                  :       ','             ;
+//DOT                  :       '.'             ;
+ASSIGN                 :       '='             ;
+EQUAL                  :       "=="    ;
+LNOT                   :       '!'             ;
+BNOT                   :       '~'             ;
+NOT_EQUAL              :       "!="    ;
+DIV                            :       '/'             ;
+DIV_ASSIGN             :       "/="    ;
+PLUS                   :       '+'             ;
+PLUS_ASSIGN            :       "+="    ;
+INC                            :       "++"    ;
+MINUS                  :       '-'             ;
+MINUS_ASSIGN   :       "-="    ;
+DEC                            :       "--"    ;
+STAR                   :       '*'             ;
+STAR_ASSIGN            :       "*="    ;
+MOD                            :       '%'             ;
+MOD_ASSIGN             :       "%="    ;
+SR                             :       ">>"    ;
+SR_ASSIGN              :       ">>="   ;
+BSR                            :       ">>>"   ;
+BSR_ASSIGN             :       ">>>="  ;
+GE                             :       ">="    ;
+GT                             :       ">"             ;
+SL                             :       "<<"    ;
+SL_ASSIGN              :       "<<="   ;
+LE                             :       "<="    ;
+LT                             :       '<'             ;
+BXOR                   :       '^'             ;
+BXOR_ASSIGN            :       "^="    ;
+BOR                            :       '|'             ;
+BOR_ASSIGN             :       "|="    ;
+LOR                            :       "||"    ;
+BAND                   :       '&'             ;
+BAND_ASSIGN            :       "&="    ;
+LAND                   :       "&&"    ;
+SEMI                   :       ';'             ;
+
+
+// Whitespace -- ignored
+WS     :       (       ' '
+               |       '\t'
+               |       '\f'
+                       // handle newlines
+               |       (       options {generateAmbigWarnings=false;}
+                       :       "\r\n"  // Evil DOS
+                       |       '\r'    // Macintosh
+                       |       '\n'    // Unix (the right way)
+                       )
+                       { newline(); }
+               )+
+               { _ttype = Token.SKIP; }
+       ;
+
+// Single-line comments
+SL_COMMENT
+       :       "//"
+               (~('\n'|'\r'))* ('\n'|'\r'('\n')?)
+               {$setType(Token.SKIP); newline();}
+       ;
+
+// multiple-line comments
+ML_COMMENT
+       :       "/*"
+               (       /*      '\r' '\n' can be matched in one alternative or by matching
+                               '\r' in one iteration and '\n' in another.  I am trying to
+                               handle any flavor of newline that comes in, but the language
+                               that allows both "\r\n" and "\r" and "\n" to all be valid
+                               newline is ambiguous.  Consequently, the resulting grammar
+                               must be ambiguous.  I'm shutting this warning off.
+                        */
+                       options {
+                               generateAmbigWarnings=false;
+                       }
+               :
+                       { LA(2)!='/' }? '*'
+               |       '\r' '\n'               {newline();}
+               |       '\r'                    {newline();}
+               |       '\n'                    {newline();}
+               |       ~('*'|'\n'|'\r')
+               )*
+               "*/"
+               {$setType(Token.SKIP);}
+       ;
+
+
+// character literals
+CHAR_LITERAL
+       :       '\'' ( ESC | ~'\'' ) '\''
+       ;
+
+// string literals
+STRING_LITERAL
+       :       '"' (ESC|~('"'|'\\'))* '"'
+       ;
+
+
+// escape sequence -- note that this is protected; it can only be called
+//   from another lexer rule -- it will not ever directly return a token to
+//   the parser
+// There are various ambiguities hushed in this rule.  The optional
+// '0'...'9' digit matches should be matched here rather than letting
+// them go back to STRING_LITERAL to be matched.  ANTLR does the
+// right thing by matching immediately; hence, it's ok to shut off
+// the FOLLOW ambig warnings.
+protected
+ESC
+       :       '\\'
+               (       'n'
+               |       'r'
+               |       't'
+               |       'b'
+               |       'f'
+               |       '"'
+               |       '\''
+               |       '\\'
+               |       ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
+               |       ('0'..'3')
+                       (
+                               options {
+                                       warnWhenFollowAmbig = false;
+                               }
+                       :       ('0'..'7')
+                               (       
+                                       options {
+                                               warnWhenFollowAmbig = false;
+                                       }
+                               :       '0'..'7'
+                               )?
+                       )?
+               |       ('4'..'7')
+                       (
+                               options {
+                                       warnWhenFollowAmbig = false;
+                               }
+                       :       ('0'..'9')
+                       )?
+               )
+       ;
+
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+       :       ('0'..'9'|'A'..'F'|'a'..'f')
+       ;
+
+
+// a dummy rule to force vocabulary to be all characters (except special
+//   ones that ANTLR uses internally (0 to 2)
+protected
+VOCAB
+       :       '\3'..'\377'
+       ;
+
+
+// an identifier.  Note that testLiterals is set to true!  This means
+// that after we match the rule, we look in the literals table to see
+// if it's a literal or really an identifer
+IDENT
+       options {testLiterals=true;}
+       :       ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')*
+       ;
+
+
+// a numeric literal
+NUM_INT
+       {boolean isDecimal=false; Token t=null;}
+    :   '.' {_ttype = DOT;}
+            (  ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
+                {
+                               if (t != null && t.getText().toUpperCase().indexOf('D')>=0) {
+                       _ttype = NUM_DOUBLE;
+                               }
+                               else {
+                       _ttype = NUM_FLOAT;
+                               }
+                               }
+            )?
+
+       |       (       '0' {isDecimal = true;} // special case for just '0'
+                       (       ('x'|'X')
+                               (                                                                                       // hex
+                                       // the 'e'|'E' and float suffix stuff look
+                                       // like hex digits, hence the (...)+ doesn't
+                                       // know when to stop: ambig.  ANTLR resolves
+                                       // it correctly by matching immediately.  It
+                                       // is therefor ok to hush warning.
+                                       options {
+                                               warnWhenFollowAmbig=false;
+                                       }
+                               :       HEX_DIGIT
+                               )+
+                       |       ('0'..'7')+                                                                     // octal
+                       )?
+               |       ('1'..'9') ('0'..'9')*  {isDecimal=true;}               // non-zero decimal
+               )
+               (       ('l'|'L') { _ttype = NUM_LONG; }
+               
+               // only check to see if it's a float if looks like decimal so far
+               |       {isDecimal}?
+            (   '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
+            |   EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
+            |   f4:FLOAT_SUFFIX {t=f4;}
+            )
+            {
+                       if (t != null && t.getText().toUpperCase() .indexOf('D') >= 0) {
+                _ttype = NUM_DOUBLE;
+                       }
+            else {
+                _ttype = NUM_FLOAT;
+                       }
+                       }
+        )?
+       ;
+
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+       :       ('e'|'E') ('+'|'-')? ('0'..'9')+
+       ;
+
+
+protected
+FLOAT_SUFFIX
+       :       'f'|'F'|'d'|'D'
+       ;
+
diff --git a/src/langs/jade/java.tree.g b/src/langs/jade/java.tree.g
new file mode 100644 (file)
index 0000000..9e58760
--- /dev/null
@@ -0,0 +1,866 @@
+header {
+//header
+}
+
+{
+//class preamble
+import JJ.*;
+import java.io.*;
+}
+
+/** Java 1.3 AST Recognizer Grammar
+ *
+ * Author: (see java.g preamble)
+ * Author: J. DeSouza
+ *
+ * Assumes that JavaTreeParser1 has been run on the AST.
+ */
+
+class JavaTreeParser extends TreeParser;
+options {
+       importVocab = Java;
+}
+{
+// Class Members
+}
+
+compilationUnit
+       :       (p:packageDefinition {
+                String name = J.pE(p.getFirstChild());
+                J.tmp.push(name);
+
+                J.ci.append((((ASTJ)p).status?"main":"") +
+                    "module " + name + " {\n");
+                J.h.append("\n#include <vector>\nusing std::vector;\n#include \"pup_stl.h\"\n");
+                J.h.append("\n#include \"jade.h\"\n");
+                J.h.append("\n#include \"" + name + ".decl.h\"\n\n");
+                J.c.append("\n#include \"" + name + ".h\"\n\n");
+                J.indentLevel++;
+            }
+        )?
+               (importDefinition)* // skip
+               (c:typeDefinition  //           { ((ClassNode)c).print(); }
+        )*
+        {
+            String name = J.pE(p.getFirstChild());
+
+            if (p != null) {
+                J.indentLevel--;
+                J.ci.append("}\n");
+                J.c.append("\n\n#include \"" + name + ".def.h\"\n");
+            }
+
+//             System.out.println("Done!");
+//             System.out.println("================ci================");
+//             System.out.println(J.ci);
+            try {
+                PrintWriter ci = new PrintWriter(new FileWriter(name + ".ci"));
+                ci.print(J.ci.toString());
+                ci.close();
+            } catch (Exception e) {
+                System.out.println(e);
+                e.printStackTrace();
+            }
+
+//             System.out.println("================.h================");
+//             System.out.println(J.h);
+            try {
+                PrintWriter h = new PrintWriter(new FileWriter(name + ".h"));
+                h.print(J.h.toString());
+                h.close();
+            } catch (Exception e) {
+                System.out.println(e);
+                e.printStackTrace();
+            }
+
+//             System.out.println("================.C================");
+//             System.out.println(J.c);
+            try {
+                PrintWriter cFile = new PrintWriter(new FileWriter(name + ".C"));
+                cFile.print(J.c.toString());
+                cFile.close();
+            } catch (Exception e) {
+                System.out.println(e);
+                e.printStackTrace();
+            }
+        }
+       ;
+
+packageDefinition // done
+       :       #( PACKAGE_DEF identifier )
+       ;
+
+importDefinition
+       :       #( IMPORT identifierStar )
+       ;
+
+typeDefinition
+       :       #(c:CLASS_DEF
+            m:modifiers
+            IDENT { J.tmp.push(#IDENT.getText()); }
+            e:extendsClause {
+
+                //{ //((ASTJ)#IDENT).genID(J.h);
+                if (J.isX(m, "synchronized")) { // is a chare
+//                     J.ciOn();
+                    if (e.getFirstChild() == null)
+                        J.fatalError( e, "synchronized class " + #IDENT.getText() + " must extend chare, charearray1d, or charearray2d");
+                    else if (e.getFirstChild().getText().equalsIgnoreCase("chare"))
+                        J.ci.append(J.indent() + (((ASTJ)c).status?"main":"") + "chare " + #IDENT.getText());
+                    else if (e.getFirstChild().getText().equalsIgnoreCase("charearray1d"))
+                        J.ci.append(J.indent() + "array [1D] " + #IDENT.getText());
+                    else if (e.getFirstChild().getText().equalsIgnoreCase("charearray2d"))
+                        J.ci.append(J.indent() + "array [2D] " + #IDENT.getText());
+                    else
+                        J.fatalError( e, "synchronized class " + #IDENT.getText() + " must extend chare, charearray1d, or charearray2d");
+                } else {
+//                     J.ciOff();
+                }
+
+                J.h.append(J.indent() + "class " + #IDENT.getText());
+//                 J.c.append(J.indent() + "class " + #IDENT.getText());
+
+                if (null != e) {
+                    StringBuffer s = new StringBuffer();
+                    s.append(": public ");
+                    AST i = e.getFirstChild();
+                    while (null != i) {
+                        if (i.getText().equalsIgnoreCase("chare")
+                            || i.getText().equalsIgnoreCase("charearray1d")
+                            || i.getText().equalsIgnoreCase("charearray2d")
+                        ) {
+                            s.append("CBase_" + #IDENT.getText());
+                        } else {
+                            s.append(J.pE(i));
+                        }
+                        i = i.getNextSibling();
+                        if (null != i) s.append(", ");
+                    }
+
+                    J.h.append(s);
+//                     J.c.append(s);
+                }
+            }
+            implementsClause // skip
+//             {
+//                 //System.out.println("Class: " + #IDENT.getText())/*#modifiers_in.getText()*/;
+//                 System.out.println(//"class " +
+//                     //((#m.getFirstChild()==null)?"":"modi_here ")  +
+//                     #IDENT.getText() + " {");
+//             }
+            o:objBlock[#IDENT, e.getFirstChild().getText().equalsIgnoreCase("charearray1d") || e.getFirstChild().getText().equalsIgnoreCase("charearray2d") ]
+        ) { J.tmp.pop(); }
+       |       #(INTERFACE_DEF modifiers IDENT extendsClause interfaceBlock )  // skip
+       ;
+
+typeSpec // done
+       :       #(TYPE typeSpecArray)
+       ;
+
+// arrays are handled in typeSpec, variableDeclarator, and
+// newExpression.  e.g. int[] a[] = new int[10][20]; the "int[]"
+// is a typeSpec, the "a[]" is a variableDeclarator, and the rest
+// is an ASSIGN newExpression.
+typeSpecArray // done
+       :       #( ARRAY_DECLARATOR typeSpecArray )
+    |   #( TEMPLATE typeSpecArray )
+       |       type
+       ;
+
+type // done
+    :  identifier
+       |       builtInType
+       ;
+
+builtInType
+    :   "void"
+    |   "boolean"
+    |   "byte"
+    |   "char"
+    |   "short"
+    |   "int"
+    |   "float"
+    |   "long"
+    |   "double"
+    ;
+
+modifiers
+       :       #( MODIFIERS (m:modifier {
+//                     if (!m.getText().equalsIgnoreCase("synchronized")) {
+//                         J.c.append(m.getText()+ " ");
+//                     }
+                }
+            )* )
+       ;
+
+modifier
+    :   "private"
+    |   "public"
+    |   "protected"
+    |   "static"
+    |   "transient"
+    |   "final"
+    |   "abstract"
+    |   "native"
+    |   "threadsafe"
+    |   "synchronized"
+    |   "const"
+    |   "volatile"
+       |       "strictfp"
+       |       "threaded"
+       |       "sync"
+       |       "readonly"
+    ;
+
+extendsClause // done
+       :       #(EXTENDS_CLAUSE (identifier)* )
+       ;
+
+implementsClause
+       :       #(IMPLEMENTS_CLAUSE (identifier)* )
+       ;
+
+interfaceBlock
+       :       #(      OBJBLOCK
+                       (       methodDecl
+                       |       variableDef[true,true]
+                       )*
+               )
+       ;
+
+objBlock[AST className, boolean insertMigrateConstructor]
+       :       #(      OBJBLOCK {
+                J.ci.append(J.indent() + " {\n");
+                J.h.append(J.indent() + " {\n");
+                J.h.append(J.indent() + "private: void _init();\n");
+                J.indentLevel++;
+                if (insertMigrateConstructor) {
+                    J.h.append(J.indent() + "public: " + J.pE(className) + "(CkMigrateMessage *m) {}\n");
+                }
+//                 J.c.append(J.indent() + " {\n");
+
+                // initialize end-class strings
+                J.endci.push(new StringBuffer(""));
+                J.endci2.push(new StringBuffer(""));
+                J.endh.push(new StringBuffer(""));
+                J.endh2.push(new StringBuffer(""));
+                J.classInit.push(new StringBuffer("void "+className.getText()+"::_init() {\n"));
+                J.endc.push(new StringBuffer(""));
+
+            }
+
+                       (       ctorDef
+                       |       m:methodDef[className]
+                       |       variableDef[true,true]
+                       |       typeDefinition
+                       |       #(STATIC_INIT slist)
+                       |       #(INSTANCE_INIT slist)
+                       )*
+            {
+                // class migration constructor is generated above
+                // Generate the class PUP method here
+                J.h.append(J.indent() + "public: virtual void pup(PUP::er &p);\n");
+                J.c.append(J.indent() + "void "+J.pE(className)+"::pup(PUP::er &p) {\n");
+                J.genPup(J.globalStack, J.pE(className));
+                J.c.append(J.indent() + "}\n");
+                ((StringBuffer)J.classInit.peek()).append("};\n");
+
+                J.indentLevel--;
+
+                // end-class wrapup code
+                J.ci.append((StringBuffer)J.endci.pop());
+                J.ci.append(J.indent() + "}\n");
+                J.ci.append((StringBuffer)J.endci2.pop());
+
+                J.h.append((StringBuffer)J.endh.pop());
+                J.h.append(J.indent() + "};\n");
+                J.h.append((StringBuffer)J.endh2.pop());
+
+                J.c.append((StringBuffer)J.classInit.pop());
+                J.c.append((StringBuffer)J.endc.pop());
+            }
+               )
+       ;
+
+ctorDef
+       :       #(c:CTOR_DEF modifiers methodHead
+            {
+                J.tmp.push("");
+                AST modifiers = #c.getFirstChild();
+                AST methodName = modifiers.getNextSibling();
+                AST parameters = methodName.getNextSibling();
+                AST tmp = parameters.getNextSibling();
+                AST throwsClause = null;
+                AST slist = null;
+                if (tmp == null) {
+                    throwsClause = null; slist = null;
+                } else if (tmp.getText().equalsIgnoreCase("throws")) {
+                    throwsClause = tmp;
+                    slist = throwsClause.getNextSibling();
+                } else {
+                    throwsClause = null; slist = tmp;
+                }
+
+                String s = methodName.getText() + "("
+                    + J.printParamList(parameters)
+                    + ")";
+
+                J.ci.append(J.indent() + "entry " + s + ";\n");// J.nl(J.ci);
+                J.h.append(J.indent() + "public: " + s + ";\n");// J.nl(J.h);
+                J.c.append(J.indent() + methodName.getText() + "::"
+                    + s + " {\n");// J.nl(J.h);
+
+                J.indentLevel++;
+                J.c.append(J.indent() + "_init();\n");
+            }
+            ctorSList
+            {
+                J.tmp.pop();
+                J.indentLevel--;
+                J.c.append(J.indent() + "}\n");// J.nl(J.h);
+            }
+        )
+       ;
+
+methodDecl
+       :       #(METHOD_DEF modifiers typeSpec methodHead)
+       ;
+
+methodDef[AST className]
+       :       #(m:METHOD_DEF modifiers ts:typeSpec mh:methodHead
+        //{ System.out.println("MethodDef " + #mh.getText()); }
+            {
+                J.tmp.push(new String(mh.getText()));
+                //System.out.println("Method: " + #m.toStringTree());
+                AST modifiers = #m.getFirstChild();
+//                 AST returnType = ((ASTJ)#m).getChild(1);
+                AST returnType = modifiers.getNextSibling();
+                AST methodName = returnType.getNextSibling();
+                AST parameters = methodName.getNextSibling();
+                AST tmp = parameters.getNextSibling();
+                AST throwsClause = null;
+                AST slist = null;
+                if (tmp == null) {
+                    throwsClause = null; slist = null;
+                } else if (tmp.getText().equalsIgnoreCase("throws")) {
+                    throwsClause = tmp;
+                    slist = throwsClause.getNextSibling();
+                } else {
+                    throwsClause = null; slist = tmp;
+                }
+
+                // entry method ?
+                if (J.isX(modifiers, "public")
+                        && returnType.getFirstChild().getType() == LITERAL_void) {
+                    //System.out.println("Method: " + #m.toStringTree());
+                    String s = methodName.getText() + "("
+                        + J.printParamList(parameters) + ")";
+                    J.ci.append(J.indent() + "entry void " + s + ";\n");
+                    J.h.append(J.indent() + "public: void " + s + ";\n");
+                    J.c.append(J.indent() + "void " + className.getText() + "::" + s + "\n");
+                }
+
+                // main method == ClassName(CkArgMsg *) == ClassName()
+                else if (methodName.getText().equalsIgnoreCase("main")) {
+                    J.ci.append(J.indent() + "entry "
+                        + className.getText() +"(CkArgMsg *);\n");
+                    J.h.append(J.indent() + "public: "
+                        + className.getText() +"(CkArgMsg *);\n");
+                    J.c.append(J.indent() //+ "public: "
+                        + className.getText() + "::" + className.getText() +"(CkArgMsg *)\n");
+                }
+
+                // regular method
+                else {
+                    String s = methodName.getText() + "("
+                        + J.printParamList(parameters) + ")";
+                    J.h.append(J.indent() + "TBD public: " + J.printTypeSpec(ts, null) + s + ";\n");
+                    J.c.append(J.indent() + "TBD public: " + J.printTypeSpec(ts, null) + className.getText() + "::" + s + "\n");
+                }
+
+//                 System.out.println("entry "
+//                     + ((modifiers.getFirstChild()==null)?"":"modi_here ")
+//                     + returnType.getFirstChild().getText() + " " //@@
+//                     + methodName.getText() + "("
+//                     + (parameters.getFirstChild() == null?"":"params_here") + ")"
+//                     + ((throwsClause != null)? " throws ": "")
+//                     + ((slist == null)? "": " slist_here ")
+//                     + ";"
+//                 );
+
+//                 J.indentLevel++;
+            }
+            (slist)?
+            {
+                J.tmp.pop();
+//                 J.indentLevel--;
+//                 J.c.append(J.indent() + "}\n");
+            }
+        )
+       ;
+
+// We can be defining a class variable or a local variable.
+// We have to intercept declarations of Chare's here.
+variableDef[boolean classVarq, boolean outputOnNewLine]
+       :       #(v:VARIABLE_DEF m:modifiers ts:typeSpec vd:variableDeclarator vi:varInitializer {
+
+                // MODIFIERS
+                // "private" "public" protected
+                // static
+                // transient
+                // final
+                // abstract
+                // native
+                // ?? threadsafe
+                // synchronized
+                // ?? const
+                // volatile
+                // strictfp
+                // threaded
+                // sync
+                // readonly
+                //
+                if (J.isX(m, new String[]{"threaded", "sync", "abstract", "native", "strictfp", "synchronized"}))
+                    J.nonfatalError(m, "Variables cannot be threaded, sync, abstract, native, strictfp, synchronized.  Ignoring.");
+                if (!classVarq)
+                    if (J.isX(m, new String[]{"private", "public", "protected"}))
+                        J.nonfatalError(m, "Only class members can be private public protected.  Ignoring.");
+                int n = ( (J.isX(m, "private")?1:0) +
+                            (J.isX(m, "public")?1:0) +
+                            (J.isX(m, "protected")?1:0) ) ;
+                if (n>1)
+                    J.fatalError(m, "Variable can only be one of private public protected.");
+
+                String varName = J.printVariableDeclarator(vd);
+
+                // class variable def
+                if (classVarq) {
+                    if (J.isX(m, "readonly")) {
+                        if (! (J.isX(m, "public") && J.isX(m, "static") ) )
+                            J.fatalError(m, "Readonly must be public static");
+                    }
+
+                    // class variable def, readonly
+                    if (J.isX(m, "public") && J.isX(m, "static") && J.isX(m, "readonly")) {
+                        if (ARRAY_DECLARATOR == ts.getType() || ARRAY_DECLARATOR == ts.getFirstChild().getType())
+                            J.fatalError(m, "readonly arrays not supported.");
+                        else if (ts.getFirstChild().getText().equalsIgnoreCase("MSA2D"))
+                            J.fatalError(m, "readonly msa not supported");
+                        // jade: module M { class C { public static readonly int ro; } }
+                        // .ci: module M { readonly int ro; }
+                        // .h: class C {}; extern int ro;
+                        // .C: int ro;
+                        String tmp = J.printTypeSpec(ts, J.mangleIfReadonly(varName)) +";\n";
+                        ((StringBuffer)J.endci2.peek()).append(J.indent() +"readonly " +tmp);
+                        ((StringBuffer)J.endh2.peek()).append(J.indent() +"extern " +tmp);
+                        ((StringBuffer)J.endc.peek()).append(
+                            J.indent() +"//readonly\n"
+                            +J.indent() +tmp);
+                        if (vi != null)
+                            J.nonfatalError(v, "Cannot initialize readonly in class. readonly can only be initialized in main.  Ignoring init.");
+
+                    // class variable def, not readonly
+                    } else {
+                        J.h.append(J.indent());
+
+                        if (J.isX(m, "public")) {
+                            J.h.append("public: ");
+                            // constant = public static final
+                            if (J.isX(m, "static") && J.isX(m, "final")){
+                                // @@ i use "const static" because with only "const" C++ does not allow an initializer.  Remove the static later, and do the initialzation in the constructor.
+                                J.h.append("const ");
+                            } else 
+                                // @@ if isChare
+                                J.nonfatalError(v, "chare variable " + varName + " cannot be public.  Proceeding anyway.");
+                        } else if (J.isX(m, "protected"))
+                            J.h.append("protected: ");
+                        else {
+                            J.h.append("private: ");
+                        }
+
+                        if (J.isX(m, "static"))
+                            J.h.append("static ");
+
+                        J.h.append(J.printTypeSpec(ts, varName));
+                        // int[][] a, becomes a.setDimension(2) in classinit
+                        if (ARRAY_DECLARATOR == ts.getType() || ARRAY_DECLARATOR == ts.getFirstChild().getType()) {
+                            AST t=ts;
+                            if (ARRAY_DECLARATOR != t.getType())
+                                t = t.getFirstChild();
+                            int i = 0;
+                            while (ARRAY_DECLARATOR == t.getType()) {
+                                ++i; t = t.getFirstChild();
+                            }
+                            ((StringBuffer)J.classInit.peek()).append(varName+".setDimension("+i+");\n"); // nD array
+                        }
+
+                        if (vi != null) {
+                            // @@ static variables should be
+                            // initialized only once per program.  Let the
+                            // class have a boolean staticInitCalled, and let
+                            // it guard a _static_init() method which is
+                            // called from the class _init().
+                            if (J.isX(m, "static")) {
+                                J.h.append(" = " + J.printExpression(vi.getFirstChild()));
+                            } else { // non-static class var init, put it into classinit
+                                String separator = "=";
+                                // Are we doing an array, i.e. = new int[]? .resize() should be put into classinit.
+                                if ((EXPR == vi.getFirstChild().getType())
+                                    && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
+                                    && (ARRAY_DECLARATOR == J.getNode(vi,"fffn").getType())) {
+                                    separator = "";
+                                }
+                                ((StringBuffer)J.classInit.peek()).append(varName + separator
+                                        + J.pE(vi.getFirstChild().getFirstChild())+";\n");
+                            }
+                        };
+                        J.h.append(";\n");
+                    }
+                }
+
+                // local variable, "new" chare, i.e. Chare a = new Hello(params);
+                // or, ChareArray a = new Hello[5];
+                else if (
+                    (ts.getFirstChild().getText().equalsIgnoreCase("chare")
+                      || ts.getFirstChild().getText().equalsIgnoreCase("charearray")
+                      || ts.getFirstChild().getText().equalsIgnoreCase("charearray2d")
+                    )
+                    && vi != null
+                    && EXPR == vi.getFirstChild().getType()
+                    && LITERAL_new == vi.getFirstChild().getFirstChild().getType()) {
+                    AST newAST = vi.getFirstChild().getFirstChild();
+//                     String cid = "_ckchareid_" + varName;
+                    String cproxytype = "CProxy_" + newAST.getFirstChild().getText();
+                    J.c.append(J.indent());
+//                     J.c.append("CkChareID " + cid + ";\n"
+//                         + J.indent() + cproxytype + "::ckNew(" + "params_here"
+//                             + ", &" + cid + ");\n"
+//                         + J.indent() + cproxytype + " " + varName + "(" + cid + ")");
+
+                    J.c.append(cproxytype + " " + varName + " = "
+                        + cproxytype + "::ckNew");
+
+                    if (ts.getFirstChild().getText().equalsIgnoreCase("chare"))
+                        // for Chare, we have an ELIST
+                        J.c.append("(" + J.printExpression(newAST.getFirstChild().getNextSibling()) +")");
+                    else if (ts.getFirstChild().getText().equalsIgnoreCase("charearray")) {
+                        // For a ChareArray, we need to go down one more level.
+                        J.c.append("(" + J.printExpression(newAST.getFirstChild().getNextSibling().getFirstChild()) +")");
+                    } else if (ts.getFirstChild().getText().equalsIgnoreCase("charearray2d")) {
+                        // For a ChareArray2D, we need to create elements using insert
+                        AST e1 = J.getNode(newAST, "fnff"); // expr in first []
+                        AST e2 = J.getNode(newAST, "fnfn"); // expr in 2nd []
+                        J.c.append("(); {int e1="
+                            +J.printExpression(e1)
+                            +"; int e2="
+                            +J.printExpression(e2)
+                            +"; for(int _i=0; _i<e1; _i++) for(int _j=0; _j<e2; _j++) "
+                            +varName+"(_i,_j).insert(); "
+                            +varName+".doneInserting();}");
+                    } else {
+                        J.internalError(v, "var def: " + v + " unexpected input");
+                    }
+                    J.c.append(";\n");
+                }
+
+                // local variable, chare with getProxy, i.e.
+                // Chare c = id.getProxy(Hello)
+                else if (ts.getFirstChild().getText().equalsIgnoreCase("chare")
+                    && vi != null
+                    && METHOD_CALL == vi.getFirstChild().getFirstChild().getType()
+                    && vi.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getText().equalsIgnoreCase("getProxy")) {
+                    String cidName = vi.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getText();
+                    String cproxytype = "CProxy_" + vi.getFirstChild().getFirstChild().getFirstChild().getNextSibling().getFirstChild().getFirstChild().getText();
+                    J.c.append(J.indent() + cproxytype + " " + varName + "(" + cidName + ");\n");
+                }
+
+                // MSA2D m = new MSA2D(a, b, c, d, ...);
+                // becomes MSA2D<a, b, c> m = new MSA2D<a, b, c>(d, ...);
+//                 else if (ts.getFirstChild().getText().equalsIgnoreCase("MSA2D")) {
+//                     System.out.println("VARIABLE_DEF: MSA2D reached");
+//                     if (outputOnNewLine) J.c.append(J.indent());
+//                     J.c.append(J.printTypeSpec(ts, varName));
+//                     if (vi == null) {
+//                         J.fatalError(vd, "MSA2D needs parameters");
+//                     } else {
+//                         J.assert1((EXPR == vi.getFirstChild().getType())
+//                             && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
+//                             && J.getNode(vi, "fff").getText().equals("MSA2D"));
+//                         AST p1 = J.getNode(vi, "fffnf");
+//                         AST p2 = p1.getNextSibling();
+//                         AST p3 = p2.getNextSibling();
+//                         J.c.append("<"+J.pE(p1)+","+J.pE(p2)+","+J.pE(p3)+"> ");
+//                         J.c.append(varName + " = new " + J.getNode(vi, "fff").getText());
+//                         J.c.append("<"+J.pE(p1)+","+J.pE(p2)+","+J.pE(p3)+"> ");
+//                         J.c.append("(" + J.pElist(p3.getNextSibling())+ ");\n");
+//                     }
+//                 }
+
+                // local non-chare/non-ChareArray variable
+                else {
+                    if (outputOnNewLine) J.c.append(J.indent());
+                    J.c.append(J.printTypeSpec(ts, varName)); // convert int[], int[][]. etc. to JArray<int>
+                    if (vi != null) {
+                        // @@ see handling of vi in class vars above.
+
+                        // Are we doing an array, i.e. = new int[], int[][], etc.
+                        if ((EXPR == vi.getFirstChild().getType())
+                            && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
+                            && (ARRAY_DECLARATOR == J.getNode(vi, "fffn").getType())) {
+                            // nD array
+                            int i = 0;
+                            AST t = J.getNode(vi, "fffn");
+                            while (ARRAY_DECLARATOR == t.getType())
+                                { ++i; t = t.getFirstChild(); }
+                            J.c.append("("+i+");" + varName);
+                        } else
+                            J.c.append(" = ");
+                        J.c.append(J.printExpression(vi.getFirstChild()));
+                    };
+                    if (outputOnNewLine) J.c.append(";\n");
+                }
+
+            }
+        )
+       ;
+
+// called from methodHead, handled there
+// called from handler, TBD
+parameterDef
+       :       #(PARAMETER_DEF modifiers typeSpec IDENT )
+       ;
+
+objectinitializer
+       :       #(INSTANCE_INIT slist)
+       ;
+
+variableDeclarator
+       :       IDENT
+       |       LBRACK variableDeclarator
+       ;
+
+varInitializer // done in variableDef
+       :       #(ASSIGN initializer)
+       |
+       ;
+
+initializer
+       :       expression // done
+       |       arrayInitializer
+       ;
+
+arrayInitializer
+       :       #(ARRAY_INIT (initializer)*)
+       ;
+
+methodHead // done in methodDef, ctorDef; TBD methodDecl
+       :       IDENT #( PARAMETERS (parameterDef)* ) (throwsClause)?
+       ;
+
+throwsClause
+       :       #( "throws" (identifier)* )
+       ;
+
+identifier // done as part of printExpression
+       :       IDENT {
+//             if (J.isChare()) J.ci.append(#IDENT.getText());
+//             J.c.append(#IDENT.getText());
+        }
+       |       #( DOT identifier IDENT {
+//             if (J.isChare()) J.ci.append("." + #IDENT.getText());
+//             J.c.append("." + #IDENT.getText());
+            }
+        )
+       ;
+
+identifierStar
+       :       IDENT
+       |       #( DOT identifier (STAR|IDENT) )
+       ;
+
+ctorSList
+       :       #( SLIST (ctorCall)? (stat)* )
+       ;
+
+slist // done
+       :       #( SLIST
+            {J.c.append(J.indent()+"{\n"); J.indentLevel++; }
+            (stat)*
+            {J.indentLevel--; J.c.append(J.indent()+"}\n");} )
+       ;
+
+stat
+    : typeDefinition  // @@ what to do about nested classes?
+       |       variableDef[false,true]  // done
+       |       e:expression { J.c.append(J.indent() + J.printExpression(e) + ";\n"); }
+       |       #(LABELED_STAT i:IDENT {J.c.append(J.pE(i)+":\n"); } stat)
+       |       #("if" ife:expression {
+                J.c.append(J.indent() + "if (" + J.printExpression(ife) + ")\n");
+            }
+            stat ({J.c.append(J.indent() + "else\n");} stat)?
+        )
+
+       |       #(      "for"
+            {
+                J.c.append(J.indent() + "for(");
+            }
+                       #(f:FOR_INIT (variableDef[false,false] | e1:elist)?)
+                       #(FOR_CONDITION (e2:expression)?)
+                       #(FOR_ITERATOR (e3:elist)?)
+            {
+                J.c.append( ((e1!=null)? J.printExpression(e1): "") +";"
+                    + J.printExpression(e2) + ";"
+                    + J.printExpression(e3) + ")");
+            }
+                       stat
+               )
+
+       |       #("while" we:expression { J.c.append(J.indent()+"while("+J.printExpression(we)+")");} stat)
+       |       #("do" {J.c.append(J.indent()+"do");}
+            stat { J.c.append(J.indent()+"while(");}
+            expression {J.c.append(");\n");})
+       |       #("break" (bi:IDENT)? {J.c.append(J.indent()+"break "+ J.pE(bi) +";\n");} )
+       |       #("continue" (ci:IDENT)? {J.c.append(J.indent()+"continue "+ J.pE(ci) +";\n");} )
+       |       #("return" (re:expression)? {J.c.append(J.indent()+"return "+ J.printExpression(re) +";\n");} )
+
+       |       #("switch" expression (caseGroup)*)
+       |       #("throw" et:expression { J.fatalError(et, "throw not supported yet");})
+       |       #("synchronized" expression stat)
+       |       t:tryBlock { J.fatalError(t, "try not supported yet");}
+       |       slist // nested SLIST // done
+       |       EMPTY_STAT { J.c.append(";\n"); } // done
+       ;
+
+caseGroup
+       :       #(CASE_GROUP (#("case" expression) | "default")+ slist)
+       ;
+
+tryBlock
+       :       #( "try" slist (handler)* (#("finally" slist))? )
+       ;
+
+handler
+       :       #( "catch" parameterDef slist )
+       ;
+
+elist // done as part of printExpression
+       :       #( ELIST (expression)*)
+       ;
+
+colonExpression
+    :   #(COLON expression expression (expression)?)
+    |   expression
+    ;
+
+expression // done as part of printExpression
+       :       #(EXPR expr)
+       ;
+
+expr // mostly done
+    :  #(QUESTION expr expr expr)      // trinary operator // done
+       |       #(ASSIGN expr expr)                     // binary operators... // done
+       |       #(PLUS_ASSIGN expr expr)// done
+       |       #(MINUS_ASSIGN expr expr)// done
+       |       #(STAR_ASSIGN expr expr)// done
+       |       #(DIV_ASSIGN expr expr)// done
+       |       #(MOD_ASSIGN expr expr)// done
+       |       #(SR_ASSIGN expr expr)// done
+       |       #(BSR_ASSIGN expr expr)// done
+       |       #(SL_ASSIGN expr expr)// done
+       |       #(BAND_ASSIGN expr expr)// done
+       |       #(BXOR_ASSIGN expr expr)// done
+       |       #(BOR_ASSIGN expr expr)// done
+       |       #(LOR expr expr)// done
+       |       #(LAND expr expr)// done
+       |       #(BOR expr expr)// done
+       |       #(BXOR expr expr)// done
+       |       #(BAND expr expr)// done
+       |       #(NOT_EQUAL expr expr)// done
+       |       #(EQUAL expr expr)// done
+       |       #(LT expr expr)// done
+       |       #(GT expr expr)// done
+       |       #(LE expr expr)// done
+       |       #(GE expr expr)// done
+       |       #(SL expr expr)// done
+       |       #(SR expr expr)// done
+       |       #(BSR expr expr)// done
+       |       #(PLUS expr expr)// done
+       |       #(MINUS expr expr)// done
+       |       #(DIV expr expr)// done
+       |       #(MOD expr expr)// done
+       |       #(STAR expr expr)// done
+       |       #(INC expr)// done
+       |       #(DEC expr)// done
+       |       #(POST_INC expr)// done
+       |       #(POST_DEC expr)// done
+       |       #(BNOT expr)// done
+       |       #(LNOT expr)// done
+       |       #("instanceof" expr expr)
+       |       #(UNARY_MINUS expr)// done
+       |       #(UNARY_PLUS expr)// done
+       |       primaryExpression
+       ;
+
+primaryExpression // done as part of printExpression
+    :   IDENT // done
+    |   #(     DOT // done
+                       (       expr // done
+                               (       IDENT // done
+                               |       arrayIndex // done
+                               |       "this"
+                               |       c:"class"
+                    //{ System.out.println("class2")/*#modifiers_in.getText()*/;}
+                               |       #( "new" IDENT elist )
+                               |   "super"
+                               )
+                       |       #(ARRAY_DECLARATOR typeSpecArray)
+                       |       builtInType ("class")?
+                       )
+               )
+       |       arrayIndex // done
+       |       #(METHOD_CALL primaryExpression elist) // done
+       |       #(TYPECAST typeSpec expr) // done
+       |   newExpression
+       |   constant// done
+    |   "super"
+    |   "true"
+    |   "false"
+    |   "this"
+    |   "null"
+       |       typeSpec // type name used with instanceof // done
+       ;
+
+ctorCall
+       :       #( CTOR_CALL elist )
+       |       #( SUPER_CTOR_CALL
+                       (       elist
+                       |       primaryExpression elist
+                       )
+                )
+       ;
+
+arrayIndex // done as part of printExpression
+       :       #(INDEX_OP primaryExpression colonExpression)
+       ;
+
+constant // done
+    :   NUM_INT
+    |   CHAR_LITERAL
+    |   STRING_LITERAL
+    |   NUM_FLOAT
+    |   NUM_DOUBLE
+    |   NUM_LONG
+    ;
+
+newExpression
+       :       #(      "new" type
+                       (       newArrayDeclarator (arrayInitializer)?
+                       |       elist (objBlock[null, false])?
+                       )
+               )
+
+       ;
+
+newArrayDeclarator
+       :       #( ARRAY_DECLARATOR (newArrayDeclarator)? (expression)? )
+       ;
diff --git a/src/langs/jade/java.tree1.g b/src/langs/jade/java.tree1.g
new file mode 100644 (file)
index 0000000..364142c
--- /dev/null
@@ -0,0 +1,369 @@
+header {
+//header
+}
+
+{
+//class preamble
+import JJ.*;
+}
+
+/** Java 1.3 AST Recognizer Grammar
+ *
+ * Author: (see java.g preamble)
+ * Author: J. DeSouza
+ *
+ * This grammar is in the PUBLIC DOMAIN
+ */
+class JavaTreeParser1 extends TreeParser;
+
+options {
+       importVocab = Java;
+}
+
+compilationUnit
+       :       (p:packageDefinition)?
+               (importDefinition)*
+               (typeDefinition[p])*
+        { if (p != null)
+            J.tmp.pop();
+        }
+       ;
+
+packageDefinition
+       :       #( PACKAGE_DEF i:identifier { J.tmp.push(J.pE(i)); })
+       ;
+
+importDefinition
+       :       #( IMPORT identifierStar )
+       ;
+
+typeDefinition[AST parent]
+       :       #(c:CLASS_DEF modifiers IDENT { J.tmp.push(#IDENT.getText()); } extendsClause implementsClause
+            o:objBlock {
+                if ( ((ASTJ)o).hasMain() ) {
+                    ((ASTJ)c).status = true; // is a mainchare
+                    ((ASTJ)parent).status = true; // is a mainmodule
+                }
+            }
+        ) { J.tmp.pop(); }
+       |       #(INTERFACE_DEF modifiers IDENT extendsClause interfaceBlock )
+       ;
+
+typeSpec
+       :       #(TYPE typeSpecArray)
+       ;
+
+typeSpecArray
+       :       #( ARRAY_DECLARATOR typeSpecArray )
+       |       type
+       ;
+
+type:  identifier
+       |       builtInType
+       ;
+
+builtInType
+    :   "void"
+    |   "boolean"
+    |   "byte"
+    |   "char"
+    |   "short"
+    |   "int"
+    |   "float"
+    |   "long"
+    |   "double"
+    ;
+
+modifiers
+       :       #( MODIFIERS (modifier)* )
+       ;
+
+modifier
+    :   "private"
+    |   "public"
+    |   "protected"
+    |   "static"
+    |   "transient"
+    |   "final"
+    |   "abstract"
+    |   "native"
+    |   "threadsafe"
+    |   "synchronized"
+    |   "const"
+    |   "volatile"
+       |       "strictfp"
+       |       "threaded"
+       |       "sync"
+       |       "readonly"
+    ;
+
+extendsClause
+       :       #(EXTENDS_CLAUSE (identifier)* )
+       ;
+
+implementsClause
+       :       #(IMPLEMENTS_CLAUSE (identifier)* )
+       ;
+
+interfaceBlock
+       :       #(      OBJBLOCK
+                       (       methodDecl
+                       |       variableDef
+                       )*
+               )
+       ;
+
+objBlock
+       :       #(      OBJBLOCK
+                       (       ctorDef
+                       |       methodDef
+                       |       variableDef
+                       |       typeDefinition[null]
+                       |       #(STATIC_INIT slist)
+                       |       #(INSTANCE_INIT slist)
+                       )*
+               )
+       ;
+
+ctorDef
+       :       #(CTOR_DEF modifiers methodHead {J.tmp.push("");} ctorSList {J.tmp.pop();})
+       ;
+
+methodDecl
+       :       #(METHOD_DEF modifiers typeSpec methodHead)
+       ;
+
+methodDef
+       :       #(METHOD_DEF modifiers typeSpec mh:methodHead
+            {
+                J.globalStack.push(new String(J.fullName(mh.getText())));
+                J.globalStackShadow.push(#METHOD_DEF);
+                J.tmp.push(new String(mh.getText()));
+            }
+            (slist)? { J.tmp.pop(); })
+       ;
+
+variableDef
+       :       #(VARIABLE_DEF m:modifiers typeSpec 
+            v:variableDeclarator {
+                //System.out.println("pass1: " + v.getText() + J.tmp + "\n");
+                if (J.tmp.size() == 2) {
+                    J.globalStack.push(new String(J.fullName(v.getText())));
+                    J.globalStackShadow.push(#VARIABLE_DEF);
+                } else {
+                    // should print this only for public static final
+                    if ( ((ASTJ)m).isX("static") )
+                      J.warning(v, "static variable " + v.getText() + " not accessible outside class.");
+                }
+            }
+            varInitializer)
+       ;
+
+parameterDef
+       :       #(PARAMETER_DEF modifiers typeSpec IDENT )
+       ;
+
+objectinitializer
+       :       #(INSTANCE_INIT slist)
+       ;
+
+variableDeclarator
+       :       IDENT
+       |       LBRACK variableDeclarator
+       ;
+
+varInitializer
+       :       #(ASSIGN initializer)
+       |
+       ;
+
+initializer
+       :       expression
+       |       arrayInitializer
+       ;
+
+arrayInitializer
+       :       #(ARRAY_INIT (initializer)*)
+       ;
+
+methodHead
+       :       IDENT #( PARAMETERS (parameterDef)* ) (throwsClause)?
+       ;
+
+throwsClause
+       :       #( "throws" (identifier)* )
+       ;
+
+identifier
+       :       IDENT
+       |       #( DOT identifier IDENT )
+       ;
+
+identifierStar
+       :       IDENT
+       |       #( DOT identifier (STAR|IDENT) )
+       ;
+
+ctorSList
+       :       #( SLIST (ctorCall)? (stat)* )
+       ;
+
+slist
+       :       #( SLIST (stat)* )
+       ;
+
+stat:  typeDefinition[null]
+       |       variableDef
+       |       expression
+       |       #(LABELED_STAT IDENT stat)
+       |       #("if" expression stat (stat)? )
+       |       #(      "for"
+                       #(FOR_INIT (variableDef | elist)?)
+                       #(FOR_CONDITION (expression)?)
+                       #(FOR_ITERATOR (elist)?)
+                       stat
+               )
+       |       #("while" expression stat)
+       |       #("do" stat expression)
+       |       #("break" (IDENT)? )
+       |       #("continue" (IDENT)? )
+       |       #("return" (expression)? )
+       |       #("switch" expression (caseGroup)*)
+       |       #("throw" expression)
+       |       #("synchronized" expression stat)
+       |       tryBlock
+       |       slist // nested SLIST
+       |       EMPTY_STAT
+       ;
+
+caseGroup
+       :       #(CASE_GROUP (#("case" expression) | "default")+ slist)
+       ;
+
+tryBlock
+       :       #( "try" slist (handler)* (#("finally" slist))? )
+       ;
+
+handler
+       :       #( "catch" parameterDef slist )
+       ;
+
+elist
+       :       #( ELIST (expression)* )
+       ;
+
+colonExpression
+    :   #(COLON expression expression (expression)?)
+    |   expression
+    ;
+
+expression
+       :       #(EXPR expr)
+       ;
+
+expr:  #(QUESTION expr expr expr)      // trinary operator
+       |       #(ASSIGN expr expr)                     // binary operators...
+       |       #(PLUS_ASSIGN expr expr)
+       |       #(MINUS_ASSIGN expr expr)
+       |       #(STAR_ASSIGN expr expr)
+       |       #(DIV_ASSIGN expr expr)
+       |       #(MOD_ASSIGN expr expr)
+       |       #(SR_ASSIGN expr expr)
+       |       #(BSR_ASSIGN expr expr)
+       |       #(SL_ASSIGN expr expr)
+       |       #(BAND_ASSIGN expr expr)
+       |       #(BXOR_ASSIGN expr expr)
+       |       #(BOR_ASSIGN expr expr)
+       |       #(LOR expr expr)
+       |       #(LAND expr expr)
+       |       #(BOR expr expr)
+       |       #(BXOR expr expr)
+       |       #(BAND expr expr)
+       |       #(NOT_EQUAL expr expr)
+       |       #(EQUAL expr expr)
+       |       #(LT expr expr)
+       |       #(GT expr expr)
+       |       #(LE expr expr)
+       |       #(GE expr expr)
+       |       #(SL expr expr)
+       |       #(SR expr expr)
+       |       #(BSR expr expr)
+       |       #(PLUS expr expr)
+       |       #(MINUS expr expr)
+       |       #(DIV expr expr)
+       |       #(MOD expr expr)
+       |       #(STAR expr expr)
+       |       #(INC expr)
+       |       #(DEC expr)
+       |       #(POST_INC expr)
+       |       #(POST_DEC expr)
+       |       #(BNOT expr)
+       |       #(LNOT expr)
+       |       #("instanceof" expr expr)
+       |       #(UNARY_MINUS expr)
+       |       #(UNARY_PLUS expr)
+       |       primaryExpression
+       ;
+
+primaryExpression
+    :   IDENT
+    |   #(     DOT
+                       (       expr
+                               (       IDENT
+                               |       arrayIndex
+                               |       "this"
+                               |       "class"
+                               |       #( "new" IDENT elist )
+                               |   "super"
+                               )
+                       |       #(ARRAY_DECLARATOR typeSpecArray)
+                       |       builtInType ("class")?
+                       )
+               )
+       |       arrayIndex
+       |       #(METHOD_CALL primaryExpression elist)
+       |       #(TYPECAST typeSpec expr)
+       |   newExpression
+       |   constant
+    |   "super"
+    |   "true"
+    |   "false"
+    |   "this"
+    |   "null"
+       |       typeSpec // type name used with instanceof
+       ;
+
+ctorCall
+       :       #( CTOR_CALL elist )
+       |       #( SUPER_CTOR_CALL
+                       (       elist
+                       |       primaryExpression elist
+                       )
+                )
+       ;
+
+arrayIndex
+       :       #(INDEX_OP primaryExpression colonExpression)
+       ;
+
+constant
+    :   NUM_INT
+    |   CHAR_LITERAL
+    |   STRING_LITERAL
+    |   NUM_FLOAT
+    |   NUM_DOUBLE
+    |   NUM_LONG
+    ;
+
+newExpression
+       :       #(      "new" type
+                       (       newArrayDeclarator (arrayInitializer)?
+                       |       elist (objBlock)?
+                       )
+               )
+                       
+       ;
+
+newArrayDeclarator
+       :       #( ARRAY_DECLARATOR (newArrayDeclarator)? (expression)? )
+       ;
index 9c055aaae622b48ab0d11edf46feb3b2bd63bc4a..9e4634cd7c48a9e7dd3a773c37981f847dc2206c 100644 (file)
@@ -78,6 +78,19 @@ translators: charmxi conv-cpm
 pose:  charm++
        cd libs/ck-libs/pose && $(MAKE)
 
+jade:
+#      make the lib, include
+       cd langs/jade && $(MAKE)
+
+# This should be done offline, since the user does not need to compile
+# parser files, etc.  All they need is the libjade + include files,
+# antlr.jar, jade.jar, and a few scripts.
+jadeall: jade
+#      make parser.g -> .java files
+       cd langs/jade && $(MAKE) p
+#      make the jade.jar file
+       cd ../../java/charm/jade && $(MAKE)
+
 LIBS: CONVLIBS CHARMLIBS
        cd libs; $(MAKE) otherlibs
 
@@ -224,6 +237,7 @@ dirs+sources:
        ./gathertree ../../src/libs libs
        ./gathertree ../../src/arch/util      .
        ./gathertree ../../src/langs langs
+       ./gathertree ../../src/langs/jade langs/jade
        ./gathertree ../../src/arch/common           .
        ./gathertree ../../src/arch/`cat .gdir`      .
        ./gatherflat ../../src/arch/`cat .vdir`      .