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