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