Initial checkin of Jade.
[charm.git] / src / langs / jade / java.tree.g
1 header {
2 //header
3 }
4
5 {
6 //class preamble
7 import JJ.*;
8 import java.io.*;
9 }
10
11 /** Java 1.3 AST Recognizer Grammar
12  *
13  * Author: (see java.g preamble)
14  * Author: J. DeSouza
15  *
16  * Assumes that JavaTreeParser1 has been run on the AST.
17  */
18
19 class JavaTreeParser extends TreeParser;
20 options {
21         importVocab = Java;
22 }
23 {
24 // Class Members
25 }
26
27 compilationUnit
28         :       (p:packageDefinition {
29                 String name = J.pE(p.getFirstChild());
30                 J.tmp.push(name);
31
32                 J.ci.append((((ASTJ)p).status?"main":"") +
33                     "module " + name + " {\n");
34                 J.h.append("\n#include <vector>\nusing std::vector;\n#include \"pup_stl.h\"\n");
35                 J.h.append("\n#include \"jade.h\"\n");
36                 J.h.append("\n#include \"" + name + ".decl.h\"\n\n");
37                 J.c.append("\n#include \"" + name + ".h\"\n\n");
38                 J.indentLevel++;
39             }
40         )?
41                 (importDefinition)* // skip
42                 (c:typeDefinition  //           { ((ClassNode)c).print(); }
43         )*
44         {
45             String name = J.pE(p.getFirstChild());
46
47             if (p != null) {
48                 J.indentLevel--;
49                 J.ci.append("}\n");
50                 J.c.append("\n\n#include \"" + name + ".def.h\"\n");
51             }
52
53 //             System.out.println("Done!");
54 //             System.out.println("================ci================");
55 //             System.out.println(J.ci);
56             try {
57                 PrintWriter ci = new PrintWriter(new FileWriter(name + ".ci"));
58                 ci.print(J.ci.toString());
59                 ci.close();
60             } catch (Exception e) {
61                 System.out.println(e);
62                 e.printStackTrace();
63             }
64
65 //             System.out.println("================.h================");
66 //             System.out.println(J.h);
67             try {
68                 PrintWriter h = new PrintWriter(new FileWriter(name + ".h"));
69                 h.print(J.h.toString());
70                 h.close();
71             } catch (Exception e) {
72                 System.out.println(e);
73                 e.printStackTrace();
74             }
75
76 //             System.out.println("================.C================");
77 //             System.out.println(J.c);
78             try {
79                 PrintWriter cFile = new PrintWriter(new FileWriter(name + ".C"));
80                 cFile.print(J.c.toString());
81                 cFile.close();
82             } catch (Exception e) {
83                 System.out.println(e);
84                 e.printStackTrace();
85             }
86         }
87         ;
88
89 packageDefinition // done
90         :       #( PACKAGE_DEF identifier )
91         ;
92
93 importDefinition
94         :       #( IMPORT identifierStar )
95         ;
96
97 typeDefinition
98         :       #(c:CLASS_DEF
99             m:modifiers
100             IDENT { J.tmp.push(#IDENT.getText()); }
101             e:extendsClause {
102
103                 //{ //((ASTJ)#IDENT).genID(J.h);
104                 if (J.isX(m, "synchronized")) { // is a chare
105 //                     J.ciOn();
106                     if (e.getFirstChild() == null)
107                         J.fatalError( e, "synchronized class " + #IDENT.getText() + " must extend chare, charearray1d, or charearray2d");
108                     else if (e.getFirstChild().getText().equalsIgnoreCase("chare"))
109                         J.ci.append(J.indent() + (((ASTJ)c).status?"main":"") + "chare " + #IDENT.getText());
110                     else if (e.getFirstChild().getText().equalsIgnoreCase("charearray1d"))
111                         J.ci.append(J.indent() + "array [1D] " + #IDENT.getText());
112                     else if (e.getFirstChild().getText().equalsIgnoreCase("charearray2d"))
113                         J.ci.append(J.indent() + "array [2D] " + #IDENT.getText());
114                     else
115                         J.fatalError( e, "synchronized class " + #IDENT.getText() + " must extend chare, charearray1d, or charearray2d");
116                 } else {
117 //                     J.ciOff();
118                 }
119
120                 J.h.append(J.indent() + "class " + #IDENT.getText());
121 //                 J.c.append(J.indent() + "class " + #IDENT.getText());
122
123                 if (null != e) {
124                     StringBuffer s = new StringBuffer();
125                     s.append(": public ");
126                     AST i = e.getFirstChild();
127                     while (null != i) {
128                         if (i.getText().equalsIgnoreCase("chare")
129                             || i.getText().equalsIgnoreCase("charearray1d")
130                             || i.getText().equalsIgnoreCase("charearray2d")
131                         ) {
132                             s.append("CBase_" + #IDENT.getText());
133                         } else {
134                             s.append(J.pE(i));
135                         }
136                         i = i.getNextSibling();
137                         if (null != i) s.append(", ");
138                     }
139
140                     J.h.append(s);
141 //                     J.c.append(s);
142                 }
143             }
144             implementsClause // skip
145 //             {
146 //                 //System.out.println("Class: " + #IDENT.getText())/*#modifiers_in.getText()*/;
147 //                 System.out.println(//"class " +
148 //                     //((#m.getFirstChild()==null)?"":"modi_here ")  +
149 //                     #IDENT.getText() + " {");
150 //             }
151             o:objBlock[#IDENT, e.getFirstChild().getText().equalsIgnoreCase("charearray1d") || e.getFirstChild().getText().equalsIgnoreCase("charearray2d") ]
152         ) { J.tmp.pop(); }
153         |       #(INTERFACE_DEF modifiers IDENT extendsClause interfaceBlock )  // skip
154         ;
155
156 typeSpec // done
157         :       #(TYPE typeSpecArray)
158         ;
159
160 // arrays are handled in typeSpec, variableDeclarator, and
161 // newExpression.  e.g. int[] a[] = new int[10][20]; the "int[]"
162 // is a typeSpec, the "a[]" is a variableDeclarator, and the rest
163 // is an ASSIGN newExpression.
164 typeSpecArray // done
165         :       #( ARRAY_DECLARATOR typeSpecArray )
166     |   #( TEMPLATE typeSpecArray )
167         |       type
168         ;
169
170 type // done
171     :   identifier
172         |       builtInType
173         ;
174
175 builtInType
176     :   "void"
177     |   "boolean"
178     |   "byte"
179     |   "char"
180     |   "short"
181     |   "int"
182     |   "float"
183     |   "long"
184     |   "double"
185     ;
186
187 modifiers
188         :       #( MODIFIERS (m:modifier {
189 //                     if (!m.getText().equalsIgnoreCase("synchronized")) {
190 //                         J.c.append(m.getText()+ " ");
191 //                     }
192                 }
193             )* )
194         ;
195
196 modifier
197     :   "private"
198     |   "public"
199     |   "protected"
200     |   "static"
201     |   "transient"
202     |   "final"
203     |   "abstract"
204     |   "native"
205     |   "threadsafe"
206     |   "synchronized"
207     |   "const"
208     |   "volatile"
209         |       "strictfp"
210         |       "threaded"
211         |       "sync"
212         |       "readonly"
213     ;
214
215 extendsClause // done
216         :       #(EXTENDS_CLAUSE (identifier)* )
217         ;
218
219 implementsClause
220         :       #(IMPLEMENTS_CLAUSE (identifier)* )
221         ;
222
223 interfaceBlock
224         :       #(      OBJBLOCK
225                         (       methodDecl
226                         |       variableDef[true,true]
227                         )*
228                 )
229         ;
230
231 objBlock[AST className, boolean insertMigrateConstructor]
232         :       #(      OBJBLOCK {
233                 J.ci.append(J.indent() + " {\n");
234                 J.h.append(J.indent() + " {\n");
235                 J.h.append(J.indent() + "private: void _init();\n");
236                 J.indentLevel++;
237                 if (insertMigrateConstructor) {
238                     J.h.append(J.indent() + "public: " + J.pE(className) + "(CkMigrateMessage *m) {}\n");
239                 }
240 //                 J.c.append(J.indent() + " {\n");
241
242                 // initialize end-class strings
243                 J.endci.push(new StringBuffer(""));
244                 J.endci2.push(new StringBuffer(""));
245                 J.endh.push(new StringBuffer(""));
246                 J.endh2.push(new StringBuffer(""));
247                 J.classInit.push(new StringBuffer("void "+className.getText()+"::_init() {\n"));
248                 J.endc.push(new StringBuffer(""));
249
250             }
251
252                         (       ctorDef
253                         |       m:methodDef[className]
254                         |       variableDef[true,true]
255                         |       typeDefinition
256                         |       #(STATIC_INIT slist)
257                         |       #(INSTANCE_INIT slist)
258                         )*
259             {
260                 // class migration constructor is generated above
261                 // Generate the class PUP method here
262                 J.h.append(J.indent() + "public: virtual void pup(PUP::er &p);\n");
263                 J.c.append(J.indent() + "void "+J.pE(className)+"::pup(PUP::er &p) {\n");
264                 J.genPup(J.globalStack, J.pE(className));
265                 J.c.append(J.indent() + "}\n");
266                 ((StringBuffer)J.classInit.peek()).append("};\n");
267
268                 J.indentLevel--;
269
270                 // end-class wrapup code
271                 J.ci.append((StringBuffer)J.endci.pop());
272                 J.ci.append(J.indent() + "}\n");
273                 J.ci.append((StringBuffer)J.endci2.pop());
274
275                 J.h.append((StringBuffer)J.endh.pop());
276                 J.h.append(J.indent() + "};\n");
277                 J.h.append((StringBuffer)J.endh2.pop());
278
279                 J.c.append((StringBuffer)J.classInit.pop());
280                 J.c.append((StringBuffer)J.endc.pop());
281             }
282                 )
283         ;
284
285 ctorDef
286         :       #(c:CTOR_DEF modifiers methodHead
287             {
288                 J.tmp.push("");
289                 AST modifiers = #c.getFirstChild();
290                 AST methodName = modifiers.getNextSibling();
291                 AST parameters = methodName.getNextSibling();
292                 AST tmp = parameters.getNextSibling();
293                 AST throwsClause = null;
294                 AST slist = null;
295                 if (tmp == null) {
296                     throwsClause = null; slist = null;
297                 } else if (tmp.getText().equalsIgnoreCase("throws")) {
298                     throwsClause = tmp;
299                     slist = throwsClause.getNextSibling();
300                 } else {
301                     throwsClause = null; slist = tmp;
302                 }
303
304                 String s = methodName.getText() + "("
305                     + J.printParamList(parameters)
306                     + ")";
307
308                 J.ci.append(J.indent() + "entry " + s + ";\n");// J.nl(J.ci);
309                 J.h.append(J.indent() + "public: " + s + ";\n");// J.nl(J.h);
310                 J.c.append(J.indent() + methodName.getText() + "::"
311                     + s + " {\n");// J.nl(J.h);
312
313                 J.indentLevel++;
314                 J.c.append(J.indent() + "_init();\n");
315             }
316             ctorSList
317             {
318                 J.tmp.pop();
319                 J.indentLevel--;
320                 J.c.append(J.indent() + "}\n");// J.nl(J.h);
321             }
322         )
323         ;
324
325 methodDecl
326         :       #(METHOD_DEF modifiers typeSpec methodHead)
327         ;
328
329 methodDef[AST className]
330         :       #(m:METHOD_DEF modifiers ts:typeSpec mh:methodHead
331         //{ System.out.println("MethodDef " + #mh.getText()); }
332             {
333                 J.tmp.push(new String(mh.getText()));
334                 //System.out.println("Method: " + #m.toStringTree());
335                 AST modifiers = #m.getFirstChild();
336 //                 AST returnType = ((ASTJ)#m).getChild(1);
337                 AST returnType = modifiers.getNextSibling();
338                 AST methodName = returnType.getNextSibling();
339                 AST parameters = methodName.getNextSibling();
340                 AST tmp = parameters.getNextSibling();
341                 AST throwsClause = null;
342                 AST slist = null;
343                 if (tmp == null) {
344                     throwsClause = null; slist = null;
345                 } else if (tmp.getText().equalsIgnoreCase("throws")) {
346                     throwsClause = tmp;
347                     slist = throwsClause.getNextSibling();
348                 } else {
349                     throwsClause = null; slist = tmp;
350                 }
351
352                 // entry method ?
353                 if (J.isX(modifiers, "public")
354                         && returnType.getFirstChild().getType() == LITERAL_void) {
355                     //System.out.println("Method: " + #m.toStringTree());
356                     String s = methodName.getText() + "("
357                         + J.printParamList(parameters) + ")";
358                     J.ci.append(J.indent() + "entry void " + s + ";\n");
359                     J.h.append(J.indent() + "public: void " + s + ";\n");
360                     J.c.append(J.indent() + "void " + className.getText() + "::" + s + "\n");
361                 }
362
363                 // main method == ClassName(CkArgMsg *) == ClassName()
364                 else if (methodName.getText().equalsIgnoreCase("main")) {
365                     J.ci.append(J.indent() + "entry "
366                         + className.getText() +"(CkArgMsg *);\n");
367                     J.h.append(J.indent() + "public: "
368                         + className.getText() +"(CkArgMsg *);\n");
369                     J.c.append(J.indent() //+ "public: "
370                         + className.getText() + "::" + className.getText() +"(CkArgMsg *)\n");
371                 }
372
373                 // regular method
374                 else {
375                     String s = methodName.getText() + "("
376                         + J.printParamList(parameters) + ")";
377                     J.h.append(J.indent() + "TBD public: " + J.printTypeSpec(ts, null) + s + ";\n");
378                     J.c.append(J.indent() + "TBD public: " + J.printTypeSpec(ts, null) + className.getText() + "::" + s + "\n");
379                 }
380
381 //                 System.out.println("entry "
382 //                     + ((modifiers.getFirstChild()==null)?"":"modi_here ")
383 //                     + returnType.getFirstChild().getText() + " " //@@
384 //                     + methodName.getText() + "("
385 //                     + (parameters.getFirstChild() == null?"":"params_here") + ")"
386 //                     + ((throwsClause != null)? " throws ": "")
387 //                     + ((slist == null)? "": " slist_here ")
388 //                     + ";"
389 //                 );
390
391 //                 J.indentLevel++;
392             }
393             (slist)?
394             {
395                 J.tmp.pop();
396 //                 J.indentLevel--;
397 //                 J.c.append(J.indent() + "}\n");
398             }
399         )
400         ;
401
402 // We can be defining a class variable or a local variable.
403 // We have to intercept declarations of Chare's here.
404 variableDef[boolean classVarq, boolean outputOnNewLine]
405         :       #(v:VARIABLE_DEF m:modifiers ts:typeSpec vd:variableDeclarator vi:varInitializer {
406
407                 // MODIFIERS
408                 // "private" "public" protected
409                 // static
410                 // transient
411                 // final
412                 // abstract
413                 // native
414                 // ?? threadsafe
415                 // synchronized
416                 // ?? const
417                 // volatile
418                 // strictfp
419                 // threaded
420                 // sync
421                 // readonly
422                 //
423                 if (J.isX(m, new String[]{"threaded", "sync", "abstract", "native", "strictfp", "synchronized"}))
424                     J.nonfatalError(m, "Variables cannot be threaded, sync, abstract, native, strictfp, synchronized.  Ignoring.");
425                 if (!classVarq)
426                     if (J.isX(m, new String[]{"private", "public", "protected"}))
427                         J.nonfatalError(m, "Only class members can be private public protected.  Ignoring.");
428                 int n = ( (J.isX(m, "private")?1:0) +
429                             (J.isX(m, "public")?1:0) +
430                             (J.isX(m, "protected")?1:0) ) ;
431                 if (n>1)
432                     J.fatalError(m, "Variable can only be one of private public protected.");
433
434                 String varName = J.printVariableDeclarator(vd);
435
436                 // class variable def
437                 if (classVarq) {
438                     if (J.isX(m, "readonly")) {
439                         if (! (J.isX(m, "public") && J.isX(m, "static") ) )
440                             J.fatalError(m, "Readonly must be public static");
441                     }
442
443                     // class variable def, readonly
444                     if (J.isX(m, "public") && J.isX(m, "static") && J.isX(m, "readonly")) {
445                         if (ARRAY_DECLARATOR == ts.getType() || ARRAY_DECLARATOR == ts.getFirstChild().getType())
446                             J.fatalError(m, "readonly arrays not supported.");
447                         else if (ts.getFirstChild().getText().equalsIgnoreCase("MSA2D"))
448                             J.fatalError(m, "readonly msa not supported");
449                         // jade: module M { class C { public static readonly int ro; } }
450                         // .ci: module M { readonly int ro; }
451                         // .h: class C {}; extern int ro;
452                         // .C: int ro;
453                         String tmp = J.printTypeSpec(ts, J.mangleIfReadonly(varName)) +";\n";
454                         ((StringBuffer)J.endci2.peek()).append(J.indent() +"readonly " +tmp);
455                         ((StringBuffer)J.endh2.peek()).append(J.indent() +"extern " +tmp);
456                         ((StringBuffer)J.endc.peek()).append(
457                             J.indent() +"//readonly\n"
458                             +J.indent() +tmp);
459                         if (vi != null)
460                             J.nonfatalError(v, "Cannot initialize readonly in class. readonly can only be initialized in main.  Ignoring init.");
461
462                     // class variable def, not readonly
463                     } else {
464                         J.h.append(J.indent());
465
466                         if (J.isX(m, "public")) {
467                             J.h.append("public: ");
468                             // constant = public static final
469                             if (J.isX(m, "static") && J.isX(m, "final")){
470                                 // @@ 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.
471                                 J.h.append("const ");
472                             } else 
473                                 // @@ if isChare
474                                 J.nonfatalError(v, "chare variable " + varName + " cannot be public.  Proceeding anyway.");
475                         } else if (J.isX(m, "protected"))
476                             J.h.append("protected: ");
477                         else {
478                             J.h.append("private: ");
479                         }
480
481                         if (J.isX(m, "static"))
482                             J.h.append("static ");
483
484                         J.h.append(J.printTypeSpec(ts, varName));
485                         // int[][] a, becomes a.setDimension(2) in classinit
486                         if (ARRAY_DECLARATOR == ts.getType() || ARRAY_DECLARATOR == ts.getFirstChild().getType()) {
487                             AST t=ts;
488                             if (ARRAY_DECLARATOR != t.getType())
489                                 t = t.getFirstChild();
490                             int i = 0;
491                             while (ARRAY_DECLARATOR == t.getType()) {
492                                 ++i; t = t.getFirstChild();
493                             }
494                             ((StringBuffer)J.classInit.peek()).append(varName+".setDimension("+i+");\n"); // nD array
495                         }
496
497                         if (vi != null) {
498                             // @@ static variables should be
499                             // initialized only once per program.  Let the
500                             // class have a boolean staticInitCalled, and let
501                             // it guard a _static_init() method which is
502                             // called from the class _init().
503                             if (J.isX(m, "static")) {
504                                 J.h.append(" = " + J.printExpression(vi.getFirstChild()));
505                             } else { // non-static class var init, put it into classinit
506                                 String separator = "=";
507                                 // Are we doing an array, i.e. = new int[]? .resize() should be put into classinit.
508                                 if ((EXPR == vi.getFirstChild().getType())
509                                     && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
510                                     && (ARRAY_DECLARATOR == J.getNode(vi,"fffn").getType())) {
511                                     separator = "";
512                                 }
513                                 ((StringBuffer)J.classInit.peek()).append(varName + separator
514                                         + J.pE(vi.getFirstChild().getFirstChild())+";\n");
515                             }
516                         };
517                         J.h.append(";\n");
518                     }
519                 }
520
521                 // local variable, "new" chare, i.e. Chare a = new Hello(params);
522                 // or, ChareArray a = new Hello[5];
523                 else if (
524                     (ts.getFirstChild().getText().equalsIgnoreCase("chare")
525                       || ts.getFirstChild().getText().equalsIgnoreCase("charearray")
526                       || ts.getFirstChild().getText().equalsIgnoreCase("charearray2d")
527                     )
528                     && vi != null
529                     && EXPR == vi.getFirstChild().getType()
530                     && LITERAL_new == vi.getFirstChild().getFirstChild().getType()) {
531                     AST newAST = vi.getFirstChild().getFirstChild();
532 //                     String cid = "_ckchareid_" + varName;
533                     String cproxytype = "CProxy_" + newAST.getFirstChild().getText();
534                     J.c.append(J.indent());
535 //                     J.c.append("CkChareID " + cid + ";\n"
536 //                         + J.indent() + cproxytype + "::ckNew(" + "params_here"
537 //                             + ", &" + cid + ");\n"
538 //                         + J.indent() + cproxytype + " " + varName + "(" + cid + ")");
539
540                     J.c.append(cproxytype + " " + varName + " = "
541                         + cproxytype + "::ckNew");
542
543                     if (ts.getFirstChild().getText().equalsIgnoreCase("chare"))
544                         // for Chare, we have an ELIST
545                         J.c.append("(" + J.printExpression(newAST.getFirstChild().getNextSibling()) +")");
546                     else if (ts.getFirstChild().getText().equalsIgnoreCase("charearray")) {
547                         // For a ChareArray, we need to go down one more level.
548                         J.c.append("(" + J.printExpression(newAST.getFirstChild().getNextSibling().getFirstChild()) +")");
549                     } else if (ts.getFirstChild().getText().equalsIgnoreCase("charearray2d")) {
550                         // For a ChareArray2D, we need to create elements using insert
551                         AST e1 = J.getNode(newAST, "fnff"); // expr in first []
552                         AST e2 = J.getNode(newAST, "fnfn"); // expr in 2nd []
553                         J.c.append("(); {int e1="
554                             +J.printExpression(e1)
555                             +"; int e2="
556                             +J.printExpression(e2)
557                             +"; for(int _i=0; _i<e1; _i++) for(int _j=0; _j<e2; _j++) "
558                             +varName+"(_i,_j).insert(); "
559                             +varName+".doneInserting();}");
560                     } else {
561                         J.internalError(v, "var def: " + v + " unexpected input");
562                     }
563                     J.c.append(";\n");
564                 }
565
566                 // local variable, chare with getProxy, i.e.
567                 // Chare c = id.getProxy(Hello)
568                 else if (ts.getFirstChild().getText().equalsIgnoreCase("chare")
569                     && vi != null
570                     && METHOD_CALL == vi.getFirstChild().getFirstChild().getType()
571                     && vi.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getText().equalsIgnoreCase("getProxy")) {
572                     String cidName = vi.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getText();
573                     String cproxytype = "CProxy_" + vi.getFirstChild().getFirstChild().getFirstChild().getNextSibling().getFirstChild().getFirstChild().getText();
574                     J.c.append(J.indent() + cproxytype + " " + varName + "(" + cidName + ");\n");
575                 }
576
577                 // MSA2D m = new MSA2D(a, b, c, d, ...);
578                 // becomes MSA2D<a, b, c> m = new MSA2D<a, b, c>(d, ...);
579 //                 else if (ts.getFirstChild().getText().equalsIgnoreCase("MSA2D")) {
580 //                     System.out.println("VARIABLE_DEF: MSA2D reached");
581 //                     if (outputOnNewLine) J.c.append(J.indent());
582 //                     J.c.append(J.printTypeSpec(ts, varName));
583 //                     if (vi == null) {
584 //                         J.fatalError(vd, "MSA2D needs parameters");
585 //                     } else {
586 //                         J.assert1((EXPR == vi.getFirstChild().getType())
587 //                             && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
588 //                             && J.getNode(vi, "fff").getText().equals("MSA2D"));
589 //                         AST p1 = J.getNode(vi, "fffnf");
590 //                         AST p2 = p1.getNextSibling();
591 //                         AST p3 = p2.getNextSibling();
592 //                         J.c.append("<"+J.pE(p1)+","+J.pE(p2)+","+J.pE(p3)+"> ");
593 //                         J.c.append(varName + " = new " + J.getNode(vi, "fff").getText());
594 //                         J.c.append("<"+J.pE(p1)+","+J.pE(p2)+","+J.pE(p3)+"> ");
595 //                         J.c.append("(" + J.pElist(p3.getNextSibling())+ ");\n");
596 //                     }
597 //                 }
598
599                 // local non-chare/non-ChareArray variable
600                 else {
601                     if (outputOnNewLine) J.c.append(J.indent());
602                     J.c.append(J.printTypeSpec(ts, varName)); // convert int[], int[][]. etc. to JArray<int>
603                     if (vi != null) {
604                         // @@ see handling of vi in class vars above.
605
606                         // Are we doing an array, i.e. = new int[], int[][], etc.
607                         if ((EXPR == vi.getFirstChild().getType())
608                             && (LITERAL_new == vi.getFirstChild().getFirstChild().getType())
609                             && (ARRAY_DECLARATOR == J.getNode(vi, "fffn").getType())) {
610                             // nD array
611                             int i = 0;
612                             AST t = J.getNode(vi, "fffn");
613                             while (ARRAY_DECLARATOR == t.getType())
614                                 { ++i; t = t.getFirstChild(); }
615                             J.c.append("("+i+");" + varName);
616                         } else
617                             J.c.append(" = ");
618                         J.c.append(J.printExpression(vi.getFirstChild()));
619                     };
620                     if (outputOnNewLine) J.c.append(";\n");
621                 }
622
623             }
624         )
625         ;
626
627 // called from methodHead, handled there
628 // called from handler, TBD
629 parameterDef
630         :       #(PARAMETER_DEF modifiers typeSpec IDENT )
631         ;
632
633 objectinitializer
634         :       #(INSTANCE_INIT slist)
635         ;
636
637 variableDeclarator
638         :       IDENT
639         |       LBRACK variableDeclarator
640         ;
641
642 varInitializer // done in variableDef
643         :       #(ASSIGN initializer)
644         |
645         ;
646
647 initializer
648         :       expression // done
649         |       arrayInitializer
650         ;
651
652 arrayInitializer
653         :       #(ARRAY_INIT (initializer)*)
654         ;
655
656 methodHead // done in methodDef, ctorDef; TBD methodDecl
657         :       IDENT #( PARAMETERS (parameterDef)* ) (throwsClause)?
658         ;
659
660 throwsClause
661         :       #( "throws" (identifier)* )
662         ;
663
664 identifier // done as part of printExpression
665         :       IDENT {
666 //             if (J.isChare()) J.ci.append(#IDENT.getText());
667 //             J.c.append(#IDENT.getText());
668         }
669         |       #( DOT identifier IDENT {
670 //             if (J.isChare()) J.ci.append("." + #IDENT.getText());
671 //             J.c.append("." + #IDENT.getText());
672             }
673         )
674         ;
675
676 identifierStar
677         :       IDENT
678         |       #( DOT identifier (STAR|IDENT) )
679         ;
680
681 ctorSList
682         :       #( SLIST (ctorCall)? (stat)* )
683         ;
684
685 slist // done
686         :       #( SLIST
687             {J.c.append(J.indent()+"{\n"); J.indentLevel++; }
688             (stat)*
689             {J.indentLevel--; J.c.append(J.indent()+"}\n");} )
690         ;
691
692 stat
693     : typeDefinition  // @@ what to do about nested classes?
694         |       variableDef[false,true]  // done
695         |       e:expression { J.c.append(J.indent() + J.printExpression(e) + ";\n"); }
696         |       #(LABELED_STAT i:IDENT {J.c.append(J.pE(i)+":\n"); } stat)
697         |       #("if" ife:expression {
698                 J.c.append(J.indent() + "if (" + J.printExpression(ife) + ")\n");
699             }
700             stat ({J.c.append(J.indent() + "else\n");} stat)?
701         )
702
703         |       #(      "for"
704             {
705                 J.c.append(J.indent() + "for(");
706             }
707                         #(f:FOR_INIT (variableDef[false,false] | e1:elist)?)
708                         #(FOR_CONDITION (e2:expression)?)
709                         #(FOR_ITERATOR (e3:elist)?)
710             {
711                 J.c.append( ((e1!=null)? J.printExpression(e1): "") +";"
712                     + J.printExpression(e2) + ";"
713                     + J.printExpression(e3) + ")");
714             }
715                         stat
716                 )
717
718         |       #("while" we:expression { J.c.append(J.indent()+"while("+J.printExpression(we)+")");} stat)
719         |       #("do" {J.c.append(J.indent()+"do");}
720             stat { J.c.append(J.indent()+"while(");}
721             expression {J.c.append(");\n");})
722         |       #("break" (bi:IDENT)? {J.c.append(J.indent()+"break "+ J.pE(bi) +";\n");} )
723         |       #("continue" (ci:IDENT)? {J.c.append(J.indent()+"continue "+ J.pE(ci) +";\n");} )
724         |       #("return" (re:expression)? {J.c.append(J.indent()+"return "+ J.printExpression(re) +";\n");} )
725
726         |       #("switch" expression (caseGroup)*)
727         |       #("throw" et:expression { J.fatalError(et, "throw not supported yet");})
728         |       #("synchronized" expression stat)
729         |       t:tryBlock { J.fatalError(t, "try not supported yet");}
730         |       slist // nested SLIST // done
731         |       EMPTY_STAT { J.c.append(";\n"); } // done
732         ;
733
734 caseGroup
735         :       #(CASE_GROUP (#("case" expression) | "default")+ slist)
736         ;
737
738 tryBlock
739         :       #( "try" slist (handler)* (#("finally" slist))? )
740         ;
741
742 handler
743         :       #( "catch" parameterDef slist )
744         ;
745
746 elist // done as part of printExpression
747         :       #( ELIST (expression)*)
748         ;
749
750 colonExpression
751     :   #(COLON expression expression (expression)?)
752     |   expression
753     ;
754
755 expression // done as part of printExpression
756         :       #(EXPR expr)
757         ;
758
759 expr // mostly done
760     :   #(QUESTION expr expr expr)      // trinary operator // done
761         |       #(ASSIGN expr expr)                     // binary operators... // done
762         |       #(PLUS_ASSIGN expr expr)// done
763         |       #(MINUS_ASSIGN expr expr)// done
764         |       #(STAR_ASSIGN expr expr)// done
765         |       #(DIV_ASSIGN expr expr)// done
766         |       #(MOD_ASSIGN expr expr)// done
767         |       #(SR_ASSIGN expr expr)// done
768         |       #(BSR_ASSIGN expr expr)// done
769         |       #(SL_ASSIGN expr expr)// done
770         |       #(BAND_ASSIGN expr expr)// done
771         |       #(BXOR_ASSIGN expr expr)// done
772         |       #(BOR_ASSIGN expr expr)// done
773         |       #(LOR expr expr)// done
774         |       #(LAND expr expr)// done
775         |       #(BOR expr expr)// done
776         |       #(BXOR expr expr)// done
777         |       #(BAND expr expr)// done
778         |       #(NOT_EQUAL expr expr)// done
779         |       #(EQUAL expr expr)// done
780         |       #(LT expr expr)// done
781         |       #(GT expr expr)// done
782         |       #(LE expr expr)// done
783         |       #(GE expr expr)// done
784         |       #(SL expr expr)// done
785         |       #(SR expr expr)// done
786         |       #(BSR expr expr)// done
787         |       #(PLUS expr expr)// done
788         |       #(MINUS expr expr)// done
789         |       #(DIV expr expr)// done
790         |       #(MOD expr expr)// done
791         |       #(STAR expr expr)// done
792         |       #(INC expr)// done
793         |       #(DEC expr)// done
794         |       #(POST_INC expr)// done
795         |       #(POST_DEC expr)// done
796         |       #(BNOT expr)// done
797         |       #(LNOT expr)// done
798         |       #("instanceof" expr expr)
799         |       #(UNARY_MINUS expr)// done
800         |       #(UNARY_PLUS expr)// done
801         |       primaryExpression
802         ;
803
804 primaryExpression // done as part of printExpression
805     :   IDENT // done
806     |   #(      DOT // done
807                         (       expr // done
808                                 (       IDENT // done
809                                 |       arrayIndex // done
810                                 |       "this"
811                                 |       c:"class"
812                     //{ System.out.println("class2")/*#modifiers_in.getText()*/;}
813                                 |       #( "new" IDENT elist )
814                                 |   "super"
815                                 )
816                         |       #(ARRAY_DECLARATOR typeSpecArray)
817                         |       builtInType ("class")?
818                         )
819                 )
820         |       arrayIndex // done
821         |       #(METHOD_CALL primaryExpression elist) // done
822         |       #(TYPECAST typeSpec expr) // done
823         |   newExpression
824         |   constant// done
825     |   "super"
826     |   "true"
827     |   "false"
828     |   "this"
829     |   "null"
830         |       typeSpec // type name used with instanceof // done
831         ;
832
833 ctorCall
834         :       #( CTOR_CALL elist )
835         |       #( SUPER_CTOR_CALL
836                         (       elist
837                         |       primaryExpression elist
838                         )
839                  )
840         ;
841
842 arrayIndex // done as part of printExpression
843         :       #(INDEX_OP primaryExpression colonExpression)
844         ;
845
846 constant // done
847     :   NUM_INT
848     |   CHAR_LITERAL
849     |   STRING_LITERAL
850     |   NUM_FLOAT
851     |   NUM_DOUBLE
852     |   NUM_LONG
853     ;
854
855 newExpression
856         :       #(      "new" type
857                         (       newArrayDeclarator (arrayInitializer)?
858                         |       elist (objBlock[null, false])?
859                         )
860                 )
861
862         ;
863
864 newArrayDeclarator
865         :       #( ARRAY_DECLARATOR (newArrayDeclarator)? (expression)? )
866         ;