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