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