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