introduce new flag -ssjava for enabling SSJava feature and start working on the imple...
[IRC.git] / Robust / src / IR / Tree / BuildIR.java
1 package IR.Tree;
2 import IR.*;
3 import Util.Lattice;
4
5 import java.util.*;
6
7 import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
8
9
10 public class BuildIR {
11   State state;
12
13   private int m_taskexitnum;
14
15   public BuildIR(State state) {
16     this.state=state;
17     this.m_taskexitnum = 0;
18   }
19
20   public void buildtree(ParseNode pn, Set toanalyze) {
21     parseFile(pn, toanalyze);
22   }
23
24   Vector singleimports;
25   Vector multiimports;
26   NameDescriptor packages;
27
28   /** Parse the classes in this file */
29   public void parseFile(ParseNode pn, Set toanalyze) {
30     singleimports=new Vector();
31     multiimports=new Vector();
32     
33     ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
34     if (ipn!=null) {
35       ParseNodeVector pnv=ipn.getChildren();
36       for(int i=0; i<pnv.size(); i++) {
37         ParseNode pnimport=pnv.elementAt(i);
38         NameDescriptor nd=parseName(pnimport.getChild("name"));
39         if (isNode(pnimport,"import_single"))
40           singleimports.add(nd);
41         else
42           multiimports.add(nd);
43       }
44     }
45     ParseNode ppn=pn.getChild("packages").getChild("package");
46     if (ppn!=null) {
47       packages=parseName(ppn.getChild("name"));
48     }
49     ParseNode tpn=pn.getChild("type_declaration_list");
50     if (tpn!=null) {
51       ParseNodeVector pnv=tpn.getChildren();
52       for(int i=0; i<pnv.size(); i++) {
53         ParseNode type_pn=pnv.elementAt(i);
54         if (isEmpty(type_pn))         /* Skip the semicolon */
55           continue;
56         if (isNode(type_pn,"class_declaration")) {
57           ClassDescriptor cn=parseTypeDecl(type_pn);
58           parseInitializers(cn);
59           if (toanalyze!=null)
60             toanalyze.add(cn);
61           state.addClass(cn);
62           // for inner classes/enum
63           HashSet tovisit = new HashSet();
64           Iterator it_icds = cn.getInnerClasses();
65           while(it_icds.hasNext()) {
66             tovisit.add(it_icds.next());
67           }
68           
69           while(!tovisit.isEmpty()) {
70             ClassDescriptor cd = (ClassDescriptor)tovisit.iterator().next();
71             tovisit.remove(cd);
72             parseInitializers(cd);
73             if(toanalyze != null) {
74               toanalyze.add(cd);
75             }
76             state.addClass(cd);
77             
78             Iterator it_ics = cd.getInnerClasses();
79             while(it_ics.hasNext()) {
80               tovisit.add(it_ics.next());
81             }
82             
83             Iterator it_ienums = cd.getEnum();
84             while(it_ienums.hasNext()) {
85               ClassDescriptor iecd = (ClassDescriptor)it_ienums.next();
86               if(toanalyze != null) {
87                 toanalyze.add(iecd);
88               }
89               state.addClass(iecd);
90             }
91           }
92           
93           Iterator it_enums = cn.getEnum();
94           while(it_enums.hasNext()) {
95             ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
96             if(toanalyze != null) {
97               toanalyze.add(ecd);
98             }
99             state.addClass(ecd);
100           }
101         } else if (isNode(type_pn,"task_declaration")) {
102           TaskDescriptor td=parseTaskDecl(type_pn);
103           if (toanalyze!=null)
104             toanalyze.add(td);
105           state.addTask(td);
106         } else if (isNode(type_pn,"interface_declaration")) {
107           // TODO add version for normal Java later
108           ClassDescriptor cn = parseInterfaceDecl(type_pn);
109           if (toanalyze!=null)
110             toanalyze.add(cn);
111           state.addClass(cn);
112           
113           // for enum
114           Iterator it_enums = cn.getEnum();
115           while(it_enums.hasNext()) {
116             ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
117             if(toanalyze != null) {
118               toanalyze.add(ecd);
119             }
120             state.addClass(ecd);
121           }
122         } else if (isNode(type_pn,"enum_declaration")) {
123           // TODO add version for normal Java later
124           ClassDescriptor cn = parseEnumDecl(null, type_pn);
125           if (toanalyze!=null)
126             toanalyze.add(cn);
127           state.addClass(cn);
128         } else {
129           throw new Error(type_pn.getLabel());
130         }
131       }
132     }
133   }
134
135  public void parseInitializers(ClassDescriptor cn){
136         Vector fv=cn.getFieldVec();
137         for(int i=0;i<fv.size();i++) {
138             FieldDescriptor fd=(FieldDescriptor)fv.get(i);
139             if(fd.getExpressionNode()!=null) {
140                 Iterator methodit = cn.getMethods();
141                 while(methodit.hasNext()){
142                     MethodDescriptor currmd=(MethodDescriptor)methodit.next();
143                     if(currmd.isConstructor()){
144                         BlockNode bn=state.getMethodBody(currmd);
145                         NameNode nn=new NameNode(new NameDescriptor(fd.getSymbol()));
146                         AssignmentNode an=new AssignmentNode(nn,fd.getExpressionNode(),new AssignOperation(1));
147                         bn.addFirstBlockStatement(new BlockExpressionNode(an));                 
148                     }
149                 }
150             }
151         }
152     }  
153
154   private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
155     ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
156     ecd.setAsEnum();
157     if(cn != null) {
158       ecd.setSurroundingClass(cn.getSymbol());
159       ecd.setSurrounding(cn);
160       cn.addEnum(ecd);
161     }
162     if (!(ecd.getSymbol().equals(TypeUtil.ObjectClass)||
163         ecd.getSymbol().equals(TypeUtil.TagClass))) {
164       ecd.setSuper(TypeUtil.ObjectClass);
165     }
166     ecd.setModifiers(parseModifiersList(pn.getChild("modifiers")));
167     parseEnumBody(ecd, pn.getChild("enumbody"));
168     return ecd;
169   }
170   
171   private void parseEnumBody(ClassDescriptor cn, ParseNode pn) {
172     ParseNode decls=pn.getChild("enum_constants_list");
173     if (decls!=null) {
174       ParseNodeVector pnv=decls.getChildren();
175       for(int i=0; i<pnv.size(); i++) {
176         ParseNode decl=pnv.elementAt(i);
177         if (isNode(decl,"enum_constant")) {
178           parseEnumConstant(cn,decl);
179         } else throw new Error();
180       }
181     }
182   }
183   
184   private void parseEnumConstant(ClassDescriptor cn, ParseNode pn) {
185     cn.addEnumConstant(pn.getChild("name").getTerminal());
186   }
187   
188   public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
189     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
190     //cn.setAsInterface();
191     if (!isEmpty(pn.getChild("superIF").getTerminal())) {
192       /* parse inherited interface name */
193       ParseNode snlist=pn.getChild("superIF").getChild("extend_interface_list");
194       ParseNodeVector pnv=snlist.getChildren();
195       for(int i=0; i<pnv.size(); i++) {
196         ParseNode decl=pnv.elementAt(i);
197         if (isNode(decl,"type")) {
198           NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
199           cn.addSuperInterface(nd.toString());
200         }
201       }
202     }
203     cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
204     parseInterfaceBody(cn, pn.getChild("interfacebody"));
205     return cn;
206   }
207   
208   private void parseInterfaceBody(ClassDescriptor cn, ParseNode pn) {
209     assert(cn.isInterface());
210     ParseNode decls=pn.getChild("interface_member_declaration_list");
211     if (decls!=null) {
212       ParseNodeVector pnv=decls.getChildren();
213       for(int i=0; i<pnv.size(); i++) {
214         ParseNode decl=pnv.elementAt(i);
215         if (isNode(decl,"constant")) {
216           parseInterfaceConstant(cn,decl);
217         } else if (isNode(decl,"method")) {
218           parseInterfaceMethod(cn,decl.getChild("method_declaration"));
219         } else throw new Error();
220       }
221     }
222   }
223   
224   private void parseInterfaceConstant(ClassDescriptor cn, ParseNode pn) {
225     if (pn!=null) {
226       parseFieldDecl(cn,pn.getChild("field_declaration"));
227       return;
228     }
229     throw new Error();
230   }
231   
232   private void parseInterfaceMethod(ClassDescriptor cn, ParseNode pn) {
233     ParseNode headern=pn.getChild("header");
234     ParseNode bodyn=pn.getChild("body");
235     MethodDescriptor md=parseMethodHeader(headern.getChild("method_header"));
236     md.getModifiers().addModifier(Modifiers.PUBLIC);
237     md.getModifiers().addModifier(Modifiers.ABSTRACT);
238     try {
239       BlockNode bn=parseBlock(bodyn);
240       cn.addMethod(md);
241       state.addTreeCode(md,bn);
242
243       // this is a hack for investigating new language features
244       // at the AST level, someday should evolve into a nice compiler
245       // option *wink*
246       //if( cn.getSymbol().equals( ***put a class in here like:     "Test" ) &&
247       //    md.getSymbol().equals( ***put your method in here like: "main" ) 
248       //) {
249       //  bn.setStyle( BlockNode.NORMAL );
250       //  System.out.println( bn.printNode( 0 ) );
251       //}
252
253     } catch (Exception e) {
254       System.out.println("Error with method:"+md.getSymbol());
255       e.printStackTrace();
256       throw new Error();
257     } catch (Error e) {
258       System.out.println("Error with method:"+md.getSymbol());
259       e.printStackTrace();
260       throw new Error();
261     }
262   }
263
264   public TaskDescriptor parseTaskDecl(ParseNode pn) {
265     TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
266     ParseNode bodyn=pn.getChild("body");
267     BlockNode bn=parseBlock(bodyn);
268     parseParameterList(td, pn);
269     state.addTreeCode(td,bn);
270     if (pn.getChild("flag_effects_list")!=null)
271       td.addFlagEffects(parseFlags(pn.getChild("flag_effects_list")));
272     return td;
273   }
274
275   public Vector parseFlags(ParseNode pn) {
276     Vector vfe=new Vector();
277     ParseNodeVector pnv=pn.getChildren();
278     for(int i=0; i<pnv.size(); i++) {
279       ParseNode fn=pnv.elementAt(i);
280       FlagEffects fe=parseFlagEffects(fn);
281       vfe.add(fe);
282     }
283     return vfe;
284   }
285
286   public FlagEffects parseFlagEffects(ParseNode pn) {
287     if (isNode(pn,"flag_effect")) {
288       String flagname=pn.getChild("name").getTerminal();
289       FlagEffects fe=new FlagEffects(flagname);
290       if (pn.getChild("flag_list")!=null)
291         parseFlagEffect(fe, pn.getChild("flag_list"));
292       if (pn.getChild("tag_list")!=null)
293         parseTagEffect(fe, pn.getChild("tag_list"));
294       return fe;
295     } else throw new Error();
296   }
297
298   public void parseTagEffect(FlagEffects fes, ParseNode pn) {
299     ParseNodeVector pnv=pn.getChildren();
300     for(int i=0; i<pnv.size(); i++) {
301       ParseNode pn2=pnv.elementAt(i);
302       boolean status=true;
303       if (isNode(pn2,"not")) {
304         status=false;
305         pn2=pn2.getChild("name");
306       }
307       String name=pn2.getTerminal();
308       fes.addTagEffect(new TagEffect(name,status));
309     }
310   }
311
312   public void parseFlagEffect(FlagEffects fes, ParseNode pn) {
313     ParseNodeVector pnv=pn.getChildren();
314     for(int i=0; i<pnv.size(); i++) {
315       ParseNode pn2=pnv.elementAt(i);
316       boolean status=true;
317       if (isNode(pn2,"not")) {
318         status=false;
319         pn2=pn2.getChild("name");
320       }
321       String name=pn2.getTerminal();
322       fes.addEffect(new FlagEffect(name,status));
323     }
324   }
325
326   public FlagExpressionNode parseFlagExpression(ParseNode pn) {
327     if (isNode(pn,"or")) {
328       ParseNodeVector pnv=pn.getChildren();
329       ParseNode left=pnv.elementAt(0);
330       ParseNode right=pnv.elementAt(1);
331       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_OR));
332     } else if (isNode(pn,"and")) {
333       ParseNodeVector pnv=pn.getChildren();
334       ParseNode left=pnv.elementAt(0);
335       ParseNode right=pnv.elementAt(1);
336       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_AND));
337     } else if (isNode(pn, "not")) {
338       ParseNodeVector pnv=pn.getChildren();
339       ParseNode left=pnv.elementAt(0);
340       return new FlagOpNode(parseFlagExpression(left), new Operation(Operation.LOGIC_NOT));
341
342     } else if (isNode(pn,"name")) {
343       return new FlagNode(pn.getTerminal());
344     } else {
345       throw new Error();
346     }
347   }
348
349   public Vector parseChecks(ParseNode pn) {
350     Vector ccs=new Vector();
351     ParseNodeVector pnv=pn.getChildren();
352     for(int i=0; i<pnv.size(); i++) {
353       ParseNode fn=pnv.elementAt(i);
354       ConstraintCheck cc=parseConstraintCheck(fn);
355       ccs.add(cc);
356     }
357     return ccs;
358   }
359
360   public ConstraintCheck parseConstraintCheck(ParseNode pn) {
361     if (isNode(pn,"cons_check")) {
362       String specname=pn.getChild("name").getChild("identifier").getTerminal();
363       Vector[] args=parseConsArgumentList(pn);
364       ConstraintCheck cc=new ConstraintCheck(specname);
365       for(int i=0; i<args[0].size(); i++) {
366         cc.addVariable((String)args[0].get(i));
367         cc.addArgument((ExpressionNode)args[1].get(i));
368       }
369       return cc;
370     } else throw new Error();
371   }
372
373   public void parseParameterList(TaskDescriptor td, ParseNode pn) {
374
375     boolean optional;
376     ParseNode paramlist=pn.getChild("task_parameter_list");
377     if (paramlist==null)
378       return;
379     ParseNodeVector pnv=paramlist.getChildren();
380     for(int i=0; i<pnv.size(); i++) {
381       ParseNode paramn=pnv.elementAt(i);
382       if(paramn.getChild("optional")!=null) {
383         optional = true;
384         paramn = paramn.getChild("optional").getFirstChild();
385         System.out.println("OPTIONAL FOUND!!!!!!!");
386       } else { optional = false;
387                System.out.println("NOT OPTIONAL");}
388
389       TypeDescriptor type=parseTypeDescriptor(paramn);
390
391       String paramname=paramn.getChild("single").getTerminal();
392       FlagExpressionNode fen=null;
393       if (paramn.getChild("flag")!=null)
394         fen=parseFlagExpression(paramn.getChild("flag").getFirstChild());
395
396       ParseNode tagnode=paramn.getChild("tag");
397
398       TagExpressionList tel=null;
399       if (tagnode!=null) {
400         tel=parseTagExpressionList(tagnode);
401       }
402
403       td.addParameter(type,paramname,fen, tel, optional);
404     }
405   }
406
407   public TagExpressionList parseTagExpressionList(ParseNode pn) {
408     //BUG FIX: change pn.getChildren() to pn.getChild("tag_expression_list").getChildren()
409     //To test, feed in any input program that uses tags
410     ParseNodeVector pnv=pn.getChild("tag_expression_list").getChildren();
411     TagExpressionList tel=new TagExpressionList();
412     for(int i=0; i<pnv.size(); i++) {
413       ParseNode tn=pnv.elementAt(i);
414       String type=tn.getChild("type").getTerminal();
415       String name=tn.getChild("single").getTerminal();
416       tel.addTag(type, name);
417     }
418     return tel;
419   }
420
421   public ClassDescriptor parseTypeDecl(ParseNode pn) {
422     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
423     if (!isEmpty(pn.getChild("super").getTerminal())) {
424       /* parse superclass name */
425       ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
426       NameDescriptor nd=parseName(snn);
427       cn.setSuper(nd.toString());
428     } else {
429       if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
430             cn.getSymbol().equals(TypeUtil.TagClass)))
431         cn.setSuper(TypeUtil.ObjectClass);
432     }
433     // check inherited interfaces
434     if (!isEmpty(pn.getChild("superIF").getTerminal())) {
435       /* parse inherited interface name */
436       ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list");
437       ParseNodeVector pnv=snlist.getChildren();
438       for(int i=0; i<pnv.size(); i++) {
439         ParseNode decl=pnv.elementAt(i);
440         if (isNode(decl,"type")) {
441           NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
442           cn.addSuperInterface(nd.toString());
443         }
444       }
445     }
446     cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
447     parseClassBody(cn, pn.getChild("classbody"));
448     
449     boolean hasConstructor = false;
450     for(Iterator method_it=cn.getMethods(); method_it.hasNext();) {
451       MethodDescriptor md=(MethodDescriptor)method_it.next();
452       hasConstructor |= md.isConstructor();
453     }
454     if((!hasConstructor) && (!cn.isEnum())) {
455       // add a default constructor for this class
456       MethodDescriptor md = new MethodDescriptor(new Modifiers(Modifiers.PUBLIC),
457           cn.getSymbol(), false);
458       BlockNode bn=new BlockNode();
459       state.addTreeCode(md,bn);
460       md.setDefaultConstructor();
461       cn.addMethod(md);
462     }
463     return cn;
464   }
465
466   private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
467     ParseNode decls=pn.getChild("class_body_declaration_list");
468     if (decls!=null) {
469       ParseNodeVector pnv=decls.getChildren();
470       for(int i=0; i<pnv.size(); i++) {
471         ParseNode decl=pnv.elementAt(i);
472         if (isNode(decl,"member")) {
473           parseClassMember(cn,decl);
474         } else if (isNode(decl,"constructor")) {
475           parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
476         } else if (isNode(decl, "static_block")) {
477           parseStaticBlockDecl(cn, decl.getChild("static_block_declaration"));
478         } else if (isNode(decl,"block")) {
479         } else if (isNode(decl,"location_order_declaration")) {
480           parseLocationOrder(cn,decl.getChild("location_order_list"));
481   } else throw new Error();
482       }
483     }
484   }
485   
486   private void parseLocationOrder(ClassDescriptor cd, ParseNode pn){
487     ParseNodeVector pnv=pn.getChildren();
488     Lattice<String> locOrder=new Lattice<String>();
489     for(int i=0; i<pnv.size(); i++) {
490       ParseNode loc=pnv.elementAt(i);
491       String lowerLoc=loc.getChildren().elementAt(0).getLabel();
492       String higherLoc=loc.getChildren().elementAt(1).getLabel();
493       locOrder.put(higherLoc, lowerLoc);
494       locOrder.put(lowerLoc,null);
495       if(locOrder.isIntroducingCycle(higherLoc)){
496         throw new Error("Error: the order relation "+lowerLoc+" < "+higherLoc+" introduces a cycle.");
497       }
498     }
499     state.addLocationOrder(cd, locOrder);
500   }
501   
502   private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
503     ParseNode fieldnode=pn.getChild("field");
504     if (fieldnode!=null) {
505       parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
506       return;
507     }
508     ParseNode methodnode=pn.getChild("method");
509     if (methodnode!=null) {
510       parseMethodDecl(cn,methodnode.getChild("method_declaration"));
511       return;
512     }
513     ParseNode innerclassnode=pn.getChild("inner_class_declaration");
514     if (innerclassnode!=null) {
515       parseInnerClassDecl(cn,innerclassnode);
516       return;
517     }
518     ParseNode enumnode=pn.getChild("enum_declaration");
519     if (enumnode!=null) {
520       parseEnumDecl(cn,enumnode);
521       return;
522     }
523     ParseNode flagnode=pn.getChild("flag");
524     if (flagnode!=null) {
525       parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
526       return;
527     }
528     // in case there are empty node
529     ParseNode emptynode=pn.getChild("empty");
530     if(emptynode != null) {
531       return;
532     }
533     throw new Error();
534   }
535   
536   private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) {
537     ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
538     icn.setAsInnerClass();
539     icn.setSurroundingClass(cn.getSymbol());
540     icn.setSurrounding(cn);
541     cn.addInnerClass(icn);
542     if (!isEmpty(pn.getChild("super").getTerminal())) {
543       /* parse superclass name */
544       ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
545       NameDescriptor nd=parseName(snn);
546       icn.setSuper(nd.toString());
547     } else {
548       if (!(icn.getSymbol().equals(TypeUtil.ObjectClass)||
549           icn.getSymbol().equals(TypeUtil.TagClass)))
550         icn.setSuper(TypeUtil.ObjectClass);
551     }
552     // check inherited interfaces
553     if (!isEmpty(pn.getChild("superIF").getTerminal())) {
554       /* parse inherited interface name */
555       ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list");
556       ParseNodeVector pnv=snlist.getChildren();
557       for(int i=0; i<pnv.size(); i++) {
558         ParseNode decl=pnv.elementAt(i);
559         if (isNode(decl,"type")) {
560           NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
561           icn.addSuperInterface(nd.toString());
562         }
563       }
564     }
565     icn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
566     if(!icn.isStatic()) {
567       throw new Error("Error: inner class " + icn.getSymbol() + " in Class " + 
568           cn.getSymbol() + " is not a nested class and is not supported yet!");
569     }
570     parseClassBody(icn, pn.getChild("classbody"));
571     return icn;
572   }
573
574   private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
575     ParseNode tn=pn.getChild("type");
576     String type_st=tn.getTerminal();
577     if(type_st.equals("byte")) {
578       return state.getTypeDescriptor(TypeDescriptor.BYTE);
579     } else if(type_st.equals("short")) {
580       return state.getTypeDescriptor(TypeDescriptor.SHORT);
581     } else if(type_st.equals("boolean")) {
582       return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
583     } else if(type_st.equals("int")) {
584       return state.getTypeDescriptor(TypeDescriptor.INT);
585     } else if(type_st.equals("long")) {
586       return state.getTypeDescriptor(TypeDescriptor.LONG);
587     } else if(type_st.equals("char")) {
588       return state.getTypeDescriptor(TypeDescriptor.CHAR);
589     } else if(type_st.equals("float")) {
590       return state.getTypeDescriptor(TypeDescriptor.FLOAT);
591     } else if(type_st.equals("double")) {
592       return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
593     } else if(type_st.equals("class")) {
594       ParseNode nn=tn.getChild("class");
595       return state.getTypeDescriptor(parseName(nn.getChild("name")));
596     } else if(type_st.equals("array")) {
597       ParseNode nn=tn.getChild("array");
598       TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
599       Integer numdims=(Integer)nn.getChild("dims").getLiteral();
600       for(int i=0; i<numdims.intValue(); i++)
601         td=td.makeArray(state);
602       return td;
603     } else {
604       System.out.println(pn.PPrint(2, true));
605       throw new Error();
606     }
607   }
608
609   private NameDescriptor parseName(ParseNode nn) {
610     ParseNode base=nn.getChild("base");
611     ParseNode id=nn.getChild("identifier");
612     if (base==null)
613       return new NameDescriptor(id.getTerminal());
614     return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
615
616   }
617
618   private void parseFlagDecl(ClassDescriptor cn,ParseNode pn) {
619     String name=pn.getChild("name").getTerminal();
620     FlagDescriptor flag=new FlagDescriptor(name);
621     if (pn.getChild("external")!=null)
622       flag.makeExternal();
623     cn.addFlag(flag);
624   }
625
626   private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
627     ParseNode mn=pn.getChild("modifier");
628     Modifiers m=parseModifiersList(mn);
629     if(cn.isInterface()) {
630       // TODO add version for normal Java later
631       // Can only be PUBLIC or STATIC or FINAL
632       if((m.isAbstract()) || (m.isAtomic()) || (m.isNative()) 
633           || (m.isSynchronized())) {
634         throw new Error("Error: field in Interface " + cn.getSymbol() + "can only be PUBLIC or STATIC or FINAL");
635       }
636       m.addModifier(Modifiers.PUBLIC);
637       m.addModifier(Modifiers.STATIC);
638       m.addModifier(Modifiers.FINAL);
639     }
640
641     ParseNode tn=pn.getChild("type");
642     TypeDescriptor t=parseTypeDescriptor(tn);
643     assignAnnotationsToType(m,t);
644     ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
645     ParseNodeVector pnv=vn.getChildren();
646     boolean isglobal=pn.getChild("global")!=null;
647
648     for(int i=0; i<pnv.size(); i++) {
649       ParseNode vardecl=pnv.elementAt(i);
650       ParseNode tmp=vardecl;
651       TypeDescriptor arrayt=t;
652       while (tmp.getChild("single")==null) {
653         arrayt=arrayt.makeArray(state);
654         tmp=tmp.getChild("array");
655       }
656       String identifier=tmp.getChild("single").getTerminal();
657       ParseNode epn=vardecl.getChild("initializer");
658
659       ExpressionNode en=null;
660       if (epn!=null) {
661         en=parseExpression(epn.getFirstChild());
662         if(m.isStatic()) {
663           // for static field, the initializer should be considered as a 
664           // static block
665           boolean isfirst = false;
666           MethodDescriptor md = (MethodDescriptor)cn.getMethodTable().getFromSameScope("staticblocks");
667           if(md == null) {
668             // the first static block for this class
669             Modifiers m_i=new Modifiers();
670             m_i.addModifier(Modifiers.STATIC);
671             md = new MethodDescriptor(m_i, "staticblocks", false);
672             md.setAsStaticBlock();
673             isfirst = true;
674           }
675           if(isfirst) {
676             cn.addMethod(md);
677           }
678           cn.incStaticBlocks();
679           BlockNode bn=new BlockNode();
680           NameNode nn=new NameNode(new NameDescriptor(identifier));
681           AssignmentNode an=new AssignmentNode(nn,en,new AssignOperation(1));
682           bn.addBlockStatement(new BlockExpressionNode(an));
683           if(isfirst) {
684             state.addTreeCode(md,bn);
685           } else {
686             BlockNode obn = state.getMethodBody(md);
687             for(int ii = 0; ii < bn.size(); ii++) {
688               BlockStatementNode bsn = bn.get(ii);
689               obn.addBlockStatement(bsn);
690             }
691             state.addTreeCode(md, obn);
692             bn = null;
693           }
694           en = null;
695         }
696       }
697
698       cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal));
699     }
700   }
701   
702   private void assignAnnotationsToType(Modifiers modifiers, TypeDescriptor type){
703     Vector<AnnotationDescriptor> annotations=modifiers.getAnnotations();
704     for(int i=0; i<annotations.size(); i++) {
705       // it only supports a marker annotation
706       AnnotationDescriptor an=annotations.elementAt(i);
707       type.addAnnotationMarker(an);           
708     }    
709   }
710
711   private ExpressionNode parseExpression(ParseNode pn) {
712     if (isNode(pn,"assignment"))
713       return parseAssignmentExpression(pn);
714     else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
715              isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
716              isNode(pn,"bitwise_and")||isNode(pn,"equal")||
717              isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
718              isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
719              isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
720              isNode(pn,"rightshift")||isNode(pn,"sub")||
721              isNode(pn,"urightshift")||isNode(pn,"sub")||
722              isNode(pn,"add")||isNode(pn,"mult")||
723              isNode(pn,"div")||isNode(pn,"mod")) {
724       ParseNodeVector pnv=pn.getChildren();
725       ParseNode left=pnv.elementAt(0);
726       ParseNode right=pnv.elementAt(1);
727       Operation op=new Operation(pn.getLabel());
728       return new OpNode(parseExpression(left),parseExpression(right),op);
729     } else if (isNode(pn,"unaryplus")||
730                isNode(pn,"unaryminus")||
731                isNode(pn,"not")||
732                isNode(pn,"comp")) {
733       ParseNode left=pn.getFirstChild();
734       Operation op=new Operation(pn.getLabel());
735       return new OpNode(parseExpression(left),op);
736     } else if (isNode(pn,"postinc")||
737                isNode(pn,"postdec")) {
738       ParseNode left=pn.getFirstChild();
739       AssignOperation op=new AssignOperation(pn.getLabel());
740       return new AssignmentNode(parseExpression(left),null,op);
741
742     } else if (isNode(pn,"preinc")||
743                isNode(pn,"predec")) {
744       ParseNode left=pn.getFirstChild();
745       AssignOperation op=isNode(pn,"preinc") ? new AssignOperation(AssignOperation.PLUSEQ) : new AssignOperation(AssignOperation.MINUSEQ);
746       return new AssignmentNode(parseExpression(left),
747                                 new LiteralNode("integer",new Integer(1)),op);
748     } else if (isNode(pn,"literal")) {
749       String literaltype=pn.getTerminal();
750       ParseNode literalnode=pn.getChild(literaltype);
751       Object literal_obj=literalnode.getLiteral();
752       return new LiteralNode(literaltype, literal_obj);
753     } else if (isNode(pn,"createobject")) {
754       TypeDescriptor td=parseTypeDescriptor(pn);
755       
756       Vector args=parseArgumentList(pn);
757       boolean isglobal=pn.getChild("global")!=null||
758         pn.getChild("scratch")!=null;
759       String disjointId=null;
760       if( pn.getChild("disjoint") != null) {
761         disjointId = pn.getChild("disjoint").getTerminal();
762       }
763       CreateObjectNode con=new CreateObjectNode(td, isglobal, disjointId);
764       for(int i=0; i<args.size(); i++) {
765         con.addArgument((ExpressionNode)args.get(i));
766       }
767       /* Could have flag set or tag added here */
768       if (pn.getChild("flag_list")!=null||pn.getChild("tag_list")!=null) {
769         FlagEffects fe=new FlagEffects(null);
770         if (pn.getChild("flag_list")!=null)
771           parseFlagEffect(fe, pn.getChild("flag_list"));
772
773         if (pn.getChild("tag_list")!=null)
774           parseTagEffect(fe, pn.getChild("tag_list"));
775         con.addFlagEffects(fe);
776       }
777
778       return con;
779     } else if (isNode(pn,"createarray")) {
780       //System.out.println(pn.PPrint(3,true));
781       boolean isglobal=pn.getChild("global")!=null||
782         pn.getChild("scratch")!=null;
783       String disjointId=null;
784       if( pn.getChild("disjoint") != null) {
785         disjointId = pn.getChild("disjoint").getTerminal();
786       }
787       TypeDescriptor td=parseTypeDescriptor(pn);
788       Vector args=parseDimExprs(pn);
789       int num=0;
790       if (pn.getChild("dims_opt").getLiteral()!=null)
791         num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
792       for(int i=0; i<(args.size()+num); i++)
793         td=td.makeArray(state);
794       CreateObjectNode con=new CreateObjectNode(td, isglobal, disjointId);
795       for(int i=0; i<args.size(); i++) {
796         con.addArgument((ExpressionNode)args.get(i));
797       }
798       return con;
799     } if (isNode(pn,"createarray2")) {
800       TypeDescriptor td=parseTypeDescriptor(pn);
801       int num=0;
802       if (pn.getChild("dims_opt").getLiteral()!=null)
803     num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
804       for(int i=0; i<num; i++)
805     td=td.makeArray(state);
806       CreateObjectNode con=new CreateObjectNode(td, false, null);
807       // TODO array initializers
808       ParseNode ipn = pn.getChild("initializer");     
809       Vector initializers=parseVariableInitializerList(ipn);
810       ArrayInitializerNode ain = new ArrayInitializerNode(initializers);
811       con.addArrayInitializer(ain);
812       return con;
813     } else if (isNode(pn,"name")) {
814       NameDescriptor nd=parseName(pn);
815       return new NameNode(nd);
816     } else if (isNode(pn,"this")) {
817       NameDescriptor nd=new NameDescriptor("this");
818       return new NameNode(nd);
819     } else if (isNode(pn,"isavailable")) {
820       NameDescriptor nd=new NameDescriptor(pn.getTerminal());
821       return new OpNode(new NameNode(nd),null,new Operation(Operation.ISAVAILABLE));
822     } else if (isNode(pn,"methodinvoke1")) {
823       NameDescriptor nd=parseName(pn.getChild("name"));
824       Vector args=parseArgumentList(pn);
825       MethodInvokeNode min=new MethodInvokeNode(nd);
826       for(int i=0; i<args.size(); i++) {
827         min.addArgument((ExpressionNode)args.get(i));
828       }
829       return min;
830     } else if (isNode(pn,"methodinvoke2")) {
831       String methodid=pn.getChild("id").getTerminal();
832       ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
833       Vector args=parseArgumentList(pn);
834       MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
835       for(int i=0; i<args.size(); i++) {
836         min.addArgument((ExpressionNode)args.get(i));
837       }
838       return min;
839     } else if (isNode(pn,"fieldaccess")) {
840       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
841       String fieldname=pn.getChild("field").getTerminal();
842       return new FieldAccessNode(en,fieldname);
843     } else if (isNode(pn,"arrayaccess")) {
844       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
845       ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
846       return new ArrayAccessNode(en,index);
847     } else if (isNode(pn,"cast1")) {
848       try {
849         return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
850       } catch (Exception e) {
851         System.out.println(pn.PPrint(1,true));
852         e.printStackTrace();
853         throw new Error();
854       }
855     } else if (isNode(pn,"cast2")) {
856       return new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
857     } else if (isNode(pn, "getoffset")) {
858       TypeDescriptor td=parseTypeDescriptor(pn);
859       String fieldname = pn.getChild("field").getTerminal();
860       //System.out.println("Checking the values of: "+ " td.toString()= " + td.toString()+ "  fieldname= " + fieldname);
861       return new OffsetNode(td, fieldname);
862     } else if (isNode(pn, "tert")) {
863       return new TertiaryNode(parseExpression(pn.getChild("cond").getFirstChild()),
864                               parseExpression(pn.getChild("trueexpr").getFirstChild()),
865                               parseExpression(pn.getChild("falseexpr").getFirstChild()) );
866     } else if (isNode(pn, "instanceof")) {
867       ExpressionNode exp=parseExpression(pn.getChild("exp").getFirstChild());
868       TypeDescriptor t=parseTypeDescriptor(pn);
869       return new InstanceOfNode(exp,t);
870     } else if (isNode(pn, "array_initializer")) {  
871       Vector initializers=parseVariableInitializerList(pn);
872       return new ArrayInitializerNode(initializers);
873     } else if (isNode(pn, "class_type")) {
874       TypeDescriptor td=parseTypeDescriptor(pn);
875       return new ClassTypeNode(td);
876     } else if (isNode(pn, "empty")) {
877       return null;
878     } else {
879       System.out.println("---------------------");
880       System.out.println(pn.PPrint(3,true));
881       throw new Error();
882     }
883   }
884
885   private Vector parseDimExprs(ParseNode pn) {
886     Vector arglist=new Vector();
887     ParseNode an=pn.getChild("dim_exprs");
888     if (an==null)       /* No argument list */
889       return arglist;
890     ParseNodeVector anv=an.getChildren();
891     for(int i=0; i<anv.size(); i++) {
892       arglist.add(parseExpression(anv.elementAt(i)));
893     }
894     return arglist;
895   }
896
897   private Vector parseArgumentList(ParseNode pn) {
898     Vector arglist=new Vector();
899     ParseNode an=pn.getChild("argument_list");
900     if (an==null)       /* No argument list */
901       return arglist;
902     ParseNodeVector anv=an.getChildren();
903     for(int i=0; i<anv.size(); i++) {
904       arglist.add(parseExpression(anv.elementAt(i)));
905     }
906     return arglist;
907   }
908
909   private Vector[] parseConsArgumentList(ParseNode pn) {
910     Vector arglist=new Vector();
911     Vector varlist=new Vector();
912     ParseNode an=pn.getChild("cons_argument_list");
913     if (an==null)       /* No argument list */
914       return new Vector[] {varlist, arglist};
915     ParseNodeVector anv=an.getChildren();
916     for(int i=0; i<anv.size(); i++) {
917       ParseNode cpn=anv.elementAt(i);
918       ParseNode var=cpn.getChild("var");
919       ParseNode exp=cpn.getChild("exp").getFirstChild();
920       varlist.add(var.getTerminal());
921       arglist.add(parseExpression(exp));
922     }
923     return new Vector[] {varlist, arglist};
924   }
925
926   private Vector parseVariableInitializerList(ParseNode pn) {
927     Vector varInitList=new Vector();
928     ParseNode vin=pn.getChild("var_init_list");
929     if (vin==null)       /* No argument list */
930       return varInitList;
931     ParseNodeVector vinv=vin.getChildren();
932     for(int i=0; i<vinv.size(); i++) {
933       varInitList.add(parseExpression(vinv.elementAt(i)));
934     }
935     return varInitList;
936   }
937
938   private ExpressionNode parseAssignmentExpression(ParseNode pn) {
939     AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
940     ParseNodeVector pnv=pn.getChild("args").getChildren();
941
942     AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
943     return an;
944   }
945
946
947   private void parseMethodDecl(ClassDescriptor cn, ParseNode pn) {
948     ParseNode headern=pn.getChild("method_header");
949     ParseNode bodyn=pn.getChild("body");
950     MethodDescriptor md=parseMethodHeader(headern);
951     try {
952       BlockNode bn=parseBlock(bodyn);
953       cn.addMethod(md);
954       state.addTreeCode(md,bn);
955
956       // this is a hack for investigating new language features
957       // at the AST level, someday should evolve into a nice compiler
958       // option *wink*
959       //if( cn.getSymbol().equals( ***put a class in here like:     "Test" ) &&
960       //    md.getSymbol().equals( ***put your method in here like: "main" ) 
961       //) {
962       //  bn.setStyle( BlockNode.NORMAL );
963       //  System.out.println( bn.printNode( 0 ) );
964       //}
965
966     } catch (Exception e) {
967       System.out.println("Error with method:"+md.getSymbol());
968       e.printStackTrace();
969       throw new Error();
970     } catch (Error e) {
971       System.out.println("Error with method:"+md.getSymbol());
972       e.printStackTrace();
973       throw new Error();
974     }
975   }
976
977   private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
978     ParseNode mn=pn.getChild("modifiers");
979     Modifiers m=parseModifiersList(mn);
980     ParseNode cdecl=pn.getChild("constructor_declarator");
981     boolean isglobal=cdecl.getChild("global")!=null;
982     String name=cdecl.getChild("name").getChild("identifier").getTerminal();
983     MethodDescriptor md=new MethodDescriptor(m, name, isglobal);
984     ParseNode paramnode=cdecl.getChild("parameters");
985     parseParameterList(md,paramnode);
986     ParseNode bodyn0=pn.getChild("body");
987     ParseNode bodyn=bodyn0.getChild("constructor_body");
988     cn.addMethod(md);
989     BlockNode bn=null;
990     if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
991       bn=parseBlock(bodyn);
992     else
993       bn=new BlockNode();
994     if (bodyn!=null&&bodyn.getChild("superinvoke")!=null) {
995       ParseNode sin=bodyn.getChild("superinvoke");
996       NameDescriptor nd=new NameDescriptor("super");
997       Vector args=parseArgumentList(sin);
998       MethodInvokeNode min=new MethodInvokeNode(nd);
999       for(int i=0; i<args.size(); i++) {
1000         min.addArgument((ExpressionNode)args.get(i));
1001       }
1002       BlockExpressionNode ben=new BlockExpressionNode(min);
1003       bn.addFirstBlockStatement(ben);
1004
1005     } else if (bodyn!=null&&bodyn.getChild("explconstrinv")!=null) {
1006       ParseNode eci=bodyn.getChild("explconstrinv");
1007       NameDescriptor nd=new NameDescriptor(cn.getSymbol());
1008       Vector args=parseArgumentList(eci);
1009       MethodInvokeNode min=new MethodInvokeNode(nd);
1010       for(int i=0; i<args.size(); i++) {
1011         min.addArgument((ExpressionNode)args.get(i));
1012       }
1013       BlockExpressionNode ben=new BlockExpressionNode(min);
1014       bn.addFirstBlockStatement(ben);
1015     }
1016     state.addTreeCode(md,bn);
1017   }
1018   
1019   private void parseStaticBlockDecl(ClassDescriptor cn, ParseNode pn) {
1020     // Each class maintains one MethodDecscriptor which combines all its 
1021     // static blocks in their declaration order
1022     boolean isfirst = false;
1023     MethodDescriptor md = (MethodDescriptor)cn.getMethodTable().getFromSameScope("staticblocks");
1024     if(md == null) {
1025       // the first static block for this class
1026       Modifiers m_i=new Modifiers();
1027       m_i.addModifier(Modifiers.STATIC);
1028       md = new MethodDescriptor(m_i, "staticblocks", false);
1029       md.setAsStaticBlock();
1030       isfirst = true;
1031     }
1032     ParseNode bodyn=pn.getChild("body");
1033     if(isfirst) {
1034       cn.addMethod(md);
1035     }
1036     cn.incStaticBlocks();
1037     BlockNode bn=null;
1038     if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
1039       bn=parseBlock(bodyn);
1040     else
1041       bn=new BlockNode();
1042     if(isfirst) {
1043       state.addTreeCode(md,bn);
1044     } else {
1045       BlockNode obn = state.getMethodBody(md);
1046       for(int i = 0; i < bn.size(); i++) {
1047         BlockStatementNode bsn = bn.get(i);
1048         obn.addBlockStatement(bsn);
1049       }
1050       state.addTreeCode(md, obn);
1051       bn = null;
1052     }
1053   }
1054
1055   public BlockNode parseBlock(ParseNode pn) {
1056     this.m_taskexitnum = 0;
1057     if (pn==null||isEmpty(pn.getTerminal()))
1058       return new BlockNode();
1059     ParseNode bsn=pn.getChild("block_statement_list");
1060     return parseBlockHelper(bsn);
1061   }
1062
1063   private BlockNode parseBlockHelper(ParseNode pn) {
1064     ParseNodeVector pnv=pn.getChildren();
1065     BlockNode bn=new BlockNode();
1066     for(int i=0; i<pnv.size(); i++) {
1067       Vector bsv=parseBlockStatement(pnv.elementAt(i));
1068       for(int j=0; j<bsv.size(); j++) {
1069         bn.addBlockStatement((BlockStatementNode)bsv.get(j));
1070       }
1071     }
1072     return bn;
1073   }
1074
1075   public BlockNode parseSingleBlock(ParseNode pn) {
1076     BlockNode bn=new BlockNode();
1077     Vector bsv=parseBlockStatement(pn);
1078     for(int j=0; j<bsv.size(); j++) {
1079       bn.addBlockStatement((BlockStatementNode)bsv.get(j));
1080     }
1081     bn.setStyle(BlockNode.NOBRACES);
1082     return bn;
1083   }
1084
1085   public Vector parseSESEBlock(Vector parentbs, ParseNode pn) {
1086     ParseNodeVector pnv=pn.getChildren();
1087     Vector bv=new Vector();
1088     for(int i=0; i<pnv.size(); i++) {
1089       bv.addAll(parseBlockStatement(pnv.elementAt(i)));
1090     }
1091     return bv;
1092   }
1093
1094   public Vector parseBlockStatement(ParseNode pn) {
1095     Vector blockstatements=new Vector();
1096     if (isNode(pn,"tag_declaration")) {
1097       String name=pn.getChild("single").getTerminal();
1098       String type=pn.getChild("type").getTerminal();
1099
1100       blockstatements.add(new TagDeclarationNode(name, type));
1101     } else if (isNode(pn,"local_variable_declaration")) {
1102       
1103       ParseNode mn=pn.getChild("modifiers");         
1104       TypeDescriptor t=parseTypeDescriptor(pn);
1105       if(mn!=null){
1106         Modifiers m=parseModifiersList(mn);
1107         assignAnnotationsToType(m, t);        
1108       }   
1109       ParseNode vn=pn.getChild("variable_declarators_list");
1110       ParseNodeVector pnv=vn.getChildren();
1111       for(int i=0; i<pnv.size(); i++) {
1112         ParseNode vardecl=pnv.elementAt(i);
1113
1114
1115         ParseNode tmp=vardecl;
1116         TypeDescriptor arrayt=t;
1117
1118         while (tmp.getChild("single")==null) {
1119           arrayt=arrayt.makeArray(state);
1120           tmp=tmp.getChild("array");
1121         }
1122         String identifier=tmp.getChild("single").getTerminal();
1123
1124         ParseNode epn=vardecl.getChild("initializer");
1125
1126
1127         ExpressionNode en=null;
1128         if (epn!=null)
1129           en=parseExpression(epn.getFirstChild());
1130
1131         blockstatements.add(new DeclarationNode(new VarDescriptor(arrayt, identifier),en));
1132       }
1133     } else if (isNode(pn,"nop")) {
1134       /* Do Nothing */
1135     } else if (isNode(pn,"expression")) {
1136       blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
1137     } else if (isNode(pn,"ifstatement")) {
1138       blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
1139                                               parseSingleBlock(pn.getChild("statement").getFirstChild()),
1140                                               pn.getChild("else_statement")!=null ? parseSingleBlock(pn.getChild("else_statement").getFirstChild()) : null));
1141     } else if (isNode(pn,"switch_statement")) {
1142       // TODO add version for normal Java later
1143       blockstatements.add(new SwitchStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
1144           parseSingleBlock(pn.getChild("statement").getFirstChild())));
1145     } else if (isNode(pn,"switch_block_list")) {
1146       // TODO add version for normal Java later
1147       ParseNodeVector pnv=pn.getChildren();
1148       for(int i=0; i<pnv.size(); i++) {
1149         ParseNode sblockdecl=pnv.elementAt(i);
1150         
1151         if(isNode(sblockdecl, "switch_block")) {
1152           ParseNode lpn=sblockdecl.getChild("switch_labels").getChild("switch_label_list");
1153           ParseNodeVector labelv=lpn.getChildren();
1154           Vector<SwitchLabelNode> slv = new Vector<SwitchLabelNode>();
1155           for(int j=0; j<labelv.size(); j++) {
1156             ParseNode labeldecl=labelv.elementAt(j);
1157             if(isNode(labeldecl, "switch_label")) {
1158               slv.addElement(new SwitchLabelNode(parseExpression(labeldecl.getChild("constant_expression").getFirstChild()), false));
1159             } else if(isNode(labeldecl, "default_switch_label")) {
1160               slv.addElement(new SwitchLabelNode(null, true));
1161             }
1162           }
1163           
1164           blockstatements.add(new SwitchBlockNode(slv, 
1165               parseSingleBlock(sblockdecl.getChild("switch_statements").getFirstChild())));
1166           
1167         }
1168       }
1169     } else if (isNode(pn, "trycatchstatement")) {
1170       // TODO add version for normal Java later
1171       // Do not fully support exceptions now. Only make sure that if there are no
1172       // exceptions thrown, the execution is right
1173       ParseNode tpn = pn.getChild("tryblock").getFirstChild();
1174       BlockNode bn=parseBlockHelper(tpn);
1175       blockstatements.add(new SubBlockNode(bn));
1176       
1177       ParseNode fbk = pn.getChild("finallyblock");
1178       if(fbk != null) {
1179         ParseNode fpn = fbk.getFirstChild();
1180         BlockNode fbn=parseBlockHelper(fpn);
1181         blockstatements.add(new SubBlockNode(fbn));
1182       }
1183     } else if (isNode(pn, "throwstatement")) {
1184       // TODO Simply return here
1185       //blockstatements.add(new ReturnNode());
1186     } else if (isNode(pn,"taskexit")) {
1187       Vector vfe=null;
1188       if (pn.getChild("flag_effects_list")!=null)
1189         vfe=parseFlags(pn.getChild("flag_effects_list"));
1190       Vector ccs=null;
1191       if (pn.getChild("cons_checks")!=null)
1192         ccs=parseChecks(pn.getChild("cons_checks"));
1193
1194       blockstatements.add(new TaskExitNode(vfe, ccs, this.m_taskexitnum++));
1195     } else if (isNode(pn,"atomic")) {
1196       BlockNode bn=parseBlockHelper(pn);
1197       blockstatements.add(new AtomicNode(bn));
1198     } else if (isNode(pn,"synchronized")) {
1199       BlockNode bn=parseBlockHelper(pn.getChild("block"));
1200       ExpressionNode en=parseExpression(pn.getChild("expr").getFirstChild());
1201       blockstatements.add(new SynchronizedNode(en, bn));
1202     } else if (isNode(pn,"return")) {
1203       if (isEmpty(pn.getTerminal()))
1204         blockstatements.add(new ReturnNode());
1205       else {
1206         ExpressionNode en=parseExpression(pn.getFirstChild());
1207         blockstatements.add(new ReturnNode(en));
1208       }
1209     } else if (isNode(pn,"block_statement_list")) {
1210       BlockNode bn=parseBlockHelper(pn);
1211       blockstatements.add(new SubBlockNode(bn));
1212     } else if (isNode(pn,"empty")) {
1213       /* nop */
1214     } else if (isNode(pn,"statement_expression_list")) {
1215       ParseNodeVector pnv=pn.getChildren();
1216       BlockNode bn=new BlockNode();
1217       for(int i=0; i<pnv.size(); i++) {
1218         ExpressionNode en=parseExpression(pnv.elementAt(i));
1219         blockstatements.add(new BlockExpressionNode(en));
1220       }
1221       bn.setStyle(BlockNode.EXPRLIST);
1222     } else if (isNode(pn,"forstatement")) {
1223       BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
1224       BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
1225       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1226       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1227       if(condition == null) {
1228         // no condition clause, make a 'true' expression as the condition
1229         condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1230       }
1231       blockstatements.add(new LoopNode(init,condition,update,body));
1232     } else if (isNode(pn,"whilestatement")) {
1233       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1234       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1235       if(condition == null) {
1236         // no condition clause, make a 'true' expression as the condition
1237         condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1238       }
1239       blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
1240     } else if (isNode(pn,"dowhilestatement")) {
1241       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1242       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1243       if(condition == null) {
1244         // no condition clause, make a 'true' expression as the condition
1245         condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1246       }
1247       blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
1248     } else if (isNode(pn,"sese")) {
1249       ParseNode pnID=pn.getChild("identifier");
1250       String stID=null;
1251       if( pnID != null ) { stID=pnID.getFirstChild().getTerminal(); }
1252       SESENode start=new SESENode(stID);
1253       SESENode end  =new SESENode(stID);
1254       start.setEnd( end   );
1255       end.setStart( start );
1256       blockstatements.add(start);
1257       blockstatements.addAll(parseSESEBlock(blockstatements,pn.getChild("body").getFirstChild()));
1258       blockstatements.add(end);
1259     } else if (isNode(pn,"continue")) {
1260       blockstatements.add(new ContinueBreakNode(false));
1261     } else if (isNode(pn,"break")) {
1262       blockstatements.add(new ContinueBreakNode(true));
1263
1264     } else if (isNode(pn,"genreach")) {
1265       String graphName = pn.getChild("graphName").getTerminal();
1266       blockstatements.add( new GenReachNode( graphName ) );
1267
1268     } else {
1269       System.out.println("---------------");
1270       System.out.println(pn.PPrint(3,true));
1271       throw new Error();
1272     }
1273     return blockstatements;
1274   }
1275
1276   public MethodDescriptor parseMethodHeader(ParseNode pn) {
1277     ParseNode mn=pn.getChild("modifiers");
1278     Modifiers m=parseModifiersList(mn);
1279
1280     ParseNode tn=pn.getChild("returntype");
1281     TypeDescriptor returntype;
1282     if (tn!=null)
1283       returntype=parseTypeDescriptor(tn);
1284     else
1285       returntype=new TypeDescriptor(TypeDescriptor.VOID);
1286
1287     ParseNode pmd=pn.getChild("method_declarator");
1288     String name=pmd.getChild("name").getTerminal();
1289     MethodDescriptor md=new MethodDescriptor(m, returntype, name);
1290
1291     ParseNode paramnode=pmd.getChild("parameters");
1292     parseParameterList(md,paramnode);
1293     return md;
1294   }
1295
1296   public void parseParameterList(MethodDescriptor md, ParseNode pn) {
1297     ParseNode paramlist=pn.getChild("formal_parameter_list");
1298     if (paramlist==null)
1299       return;
1300     ParseNodeVector pnv=paramlist.getChildren();
1301     for(int i=0; i<pnv.size(); i++) {
1302       ParseNode paramn=pnv.elementAt(i);
1303
1304       if (isNode(paramn, "tag_parameter")) {
1305         String paramname=paramn.getChild("single").getTerminal();
1306         TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
1307         md.addTagParameter(type, paramname);
1308       } else {
1309         TypeDescriptor type=parseTypeDescriptor(paramn);
1310
1311         ParseNode tmp=paramn;
1312         while (tmp.getChild("single")==null) {
1313           type=type.makeArray(state);
1314           tmp=tmp.getChild("array");
1315         }
1316         String paramname=tmp.getChild("single").getTerminal();
1317
1318         md.addParameter(type, paramname);
1319       }
1320     }
1321   }
1322
1323   public Modifiers parseModifiersList(ParseNode pn) {
1324     Modifiers m=new Modifiers();
1325     ParseNode modlist=pn.getChild("modifier_list");
1326     if (modlist!=null) {
1327       ParseNodeVector pnv=modlist.getChildren();
1328       for(int i=0; i<pnv.size(); i++) {
1329         ParseNode modn=pnv.elementAt(i);        
1330         if (isNode(modn,"public"))
1331           m.addModifier(Modifiers.PUBLIC);
1332         else if (isNode(modn,"protected"))
1333           m.addModifier(Modifiers.PROTECTED);
1334         else if (isNode(modn,"private"))
1335           m.addModifier(Modifiers.PRIVATE);
1336         else if (isNode(modn,"static"))
1337           m.addModifier(Modifiers.STATIC);
1338         else if (isNode(modn,"final"))
1339           m.addModifier(Modifiers.FINAL);
1340         else if (isNode(modn,"native"))
1341           m.addModifier(Modifiers.NATIVE);
1342         else if (isNode(modn,"synchronized"))
1343           m.addModifier(Modifiers.SYNCHRONIZED);
1344         else if (isNode(modn,"atomic"))
1345           m.addModifier(Modifiers.ATOMIC);
1346     else if (isNode(modn,"abstract"))
1347       m.addModifier(Modifiers.ABSTRACT);
1348     else if (isNode(modn,"volatile"))
1349       m.addModifier(Modifiers.VOLATILE);
1350     else if (isNode(modn,"transient"))
1351       m.addModifier(Modifiers.TRANSIENT);
1352     else if(isNode(modn,"annotation_list"))
1353       parseAnnotationList(modn,m);    
1354         else{     
1355           throw new Error("Unrecognized Modifier:"+modn.getLabel());}
1356       }
1357     }
1358     return m;
1359   }
1360   
1361   private void parseAnnotationList(ParseNode pn, Modifiers m){
1362       ParseNodeVector pnv=pn.getChildren();
1363       for(int i=0; i<pnv.size(); i++) {
1364         ParseNode body_list=pnv.elementAt(i);
1365         if(isNode(body_list,"annotation_body")){
1366           ParseNode body_node=body_list.getFirstChild();
1367           if (isNode(body_node,"marker_annotation")){          
1368             m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal()));
1369           }else if(isNode(body_node,"single_annotation")){
1370             throw new Error("Annotation with single piece of data is not supported yet.");
1371           } else if(isNode(body_node,"normal_annotation")){
1372             throw new Error("Annotation with multiple data members is not supported yet.");
1373           }   
1374         }
1375       }    
1376   }
1377
1378   private boolean isNode(ParseNode pn, String label) {
1379     if (pn.getLabel().equals(label))
1380       return true;
1381     else return false;
1382   }
1383
1384   private static boolean isEmpty(ParseNode pn) {
1385     if (pn.getLabel().equals("empty"))
1386       return true;
1387     else
1388       return false;
1389   }
1390
1391   private static boolean isEmpty(String s) {
1392     if (s.equals("empty"))
1393       return true;
1394     else
1395       return false;
1396   }
1397
1398   /** Throw an exception if something is unexpected */
1399   private void check(ParseNode pn, String label) {
1400     if (pn == null) {
1401       throw new Error(pn+ "IE: Expected '" + label + "', got null");
1402     }
1403     if (!pn.getLabel().equals(label)) {
1404       throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
1405     }
1406   }
1407 }