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