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