This commit was manufactured by cvs2svn to create tag 'buildscript'.
[IRC.git] /
1 package IR.Tree;
2 import IR.*;
3 import java.util.*;
4
5
6 public class BuildIR {
7   State state;
8   
9   private int m_taskexitnum;
10   
11   public BuildIR(State state) {
12     this.state=state;
13     this.m_taskexitnum = 0;
14   }
15   
16   public void buildtree() {
17     for(Iterator it=state.parsetrees.iterator(); it.hasNext();) {
18       ParseNode pn=(ParseNode)it.next();
19       parseFile(pn);
20     }
21   }
22
23   /** Parse the classes in this file */
24   public void parseFile(ParseNode pn) {
25     NameDescriptor packages;
26     Vector singleimports=new Vector();
27     Vector multiimports=new Vector();
28
29     ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
30     if (ipn!=null) {
31       ParseNodeVector pnv=ipn.getChildren();
32       for(int i=0; i<pnv.size(); i++) {
33         ParseNode pnimport=pnv.elementAt(i);
34         NameDescriptor nd=parseName(pnimport.getChild("name"));
35         if (isNode(pnimport,"import_single"))
36           singleimports.add(nd);
37         else
38           multiimports.add(nd);
39       }
40     }
41     ParseNode ppn=pn.getChild("packages").getChild("package");
42     if (ppn!=null) {
43       packages=parseName(pn.getChild("name"));
44     }
45     ParseNode tpn=pn.getChild("type_declaration_list");
46     if (tpn!=null) {
47       ParseNodeVector pnv=tpn.getChildren();
48       for(int i=0; i<pnv.size(); i++) {
49         ParseNode type_pn=pnv.elementAt(i);
50         if (isEmpty(type_pn))         /* Skip the semicolon */
51           continue;
52         if (isNode(type_pn,"class_declaration")) {
53           ClassDescriptor cn=parseTypeDecl(type_pn);
54           state.addClass(cn);
55         } else if (isNode(type_pn,"task_declaration")) {
56           TaskDescriptor td=parseTaskDecl(type_pn);
57           state.addTask(td);
58         } else {
59           throw new Error(type_pn.getLabel());
60         }
61       }
62     }
63   }
64
65   public TaskDescriptor parseTaskDecl(ParseNode pn) {
66     TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
67     ParseNode bodyn=pn.getChild("body");
68     BlockNode bn=parseBlock(bodyn);
69     parseParameterList(td, pn);
70     state.addTreeCode(td,bn);
71     if (pn.getChild("flag_effects_list")!=null)
72       td.addFlagEffects(parseFlags(pn.getChild("flag_effects_list")));
73     return td;
74   }
75
76   public Vector parseFlags(ParseNode pn) {
77     Vector vfe=new Vector();
78     ParseNodeVector pnv=pn.getChildren();
79     for(int i=0; i<pnv.size(); i++) {
80       ParseNode fn=pnv.elementAt(i);
81       FlagEffects fe=parseFlagEffects(fn);
82       vfe.add(fe);
83     }
84     return vfe;
85   }
86
87   public FlagEffects parseFlagEffects(ParseNode pn) {
88     if (isNode(pn,"flag_effect")) {
89       String flagname=pn.getChild("name").getTerminal();
90       FlagEffects fe=new FlagEffects(flagname);
91       if (pn.getChild("flag_list")!=null)
92         parseFlagEffect(fe, pn.getChild("flag_list"));
93       if (pn.getChild("tag_list")!=null)
94         parseTagEffect(fe, pn.getChild("tag_list"));
95       return fe;
96     } else throw new Error();
97   }
98
99   public void parseTagEffect(FlagEffects fes, ParseNode pn) {
100     ParseNodeVector pnv=pn.getChildren();
101     for(int i=0; i<pnv.size(); i++) {
102       ParseNode pn2=pnv.elementAt(i);
103       boolean status=true;
104       if (isNode(pn2,"not")) {
105         status=false;
106         pn2=pn2.getChild("name");
107       }
108       String name=pn2.getTerminal();
109       fes.addTagEffect(new TagEffect(name,status));
110     }
111   }
112
113   public void parseFlagEffect(FlagEffects fes, ParseNode pn) {
114     ParseNodeVector pnv=pn.getChildren();
115     for(int i=0; i<pnv.size(); i++) {
116       ParseNode pn2=pnv.elementAt(i);
117       boolean status=true;
118       if (isNode(pn2,"not")) {
119         status=false;
120         pn2=pn2.getChild("name");
121       }
122       String name=pn2.getTerminal();
123       fes.addEffect(new FlagEffect(name,status));
124     }
125   }
126
127   public FlagExpressionNode parseFlagExpression(ParseNode pn) {
128     if (isNode(pn,"or")) {
129       ParseNodeVector pnv=pn.getChildren();
130       ParseNode left=pnv.elementAt(0);
131       ParseNode right=pnv.elementAt(1);
132       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_OR));
133     } else if (isNode(pn,"and")) {
134       ParseNodeVector pnv=pn.getChildren();
135       ParseNode left=pnv.elementAt(0);
136       ParseNode right=pnv.elementAt(1);
137       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_AND));
138     } else if (isNode(pn, "not")) {
139       ParseNodeVector pnv=pn.getChildren();
140       ParseNode left=pnv.elementAt(0);
141       return new FlagOpNode(parseFlagExpression(left), new Operation(Operation.LOGIC_NOT));
142
143     } else if (isNode(pn,"name")) {
144       return new FlagNode(pn.getTerminal());
145     } else {
146       throw new Error();
147     }
148   }
149
150   public Vector parseChecks(ParseNode pn) {
151     Vector ccs=new Vector();
152     ParseNodeVector pnv=pn.getChildren();
153     for(int i=0; i<pnv.size(); i++) {
154       ParseNode fn=pnv.elementAt(i);
155       ConstraintCheck cc=parseConstraintCheck(fn);
156       ccs.add(cc);
157     }
158     return ccs;
159   }
160
161   public ConstraintCheck parseConstraintCheck(ParseNode pn) {
162     if (isNode(pn,"cons_check")) {
163       String specname=pn.getChild("name").getChild("identifier").getTerminal();
164       Vector[] args=parseConsArgumentList(pn);
165       ConstraintCheck cc=new ConstraintCheck(specname);
166       for(int i=0; i<args[0].size(); i++) {
167         cc.addVariable((String)args[0].get(i));
168         cc.addArgument((ExpressionNode)args[1].get(i));
169       }
170       return cc;
171     } else throw new Error();
172   }
173
174   public void parseParameterList(TaskDescriptor td, ParseNode pn) {
175
176     boolean optional;
177     ParseNode paramlist=pn.getChild("task_parameter_list");
178     if (paramlist==null)
179       return;
180     ParseNodeVector pnv=paramlist.getChildren();
181     for(int i=0; i<pnv.size(); i++) {
182       ParseNode paramn=pnv.elementAt(i);
183       if(paramn.getChild("optional")!=null) {
184         optional = true;
185         paramn = paramn.getChild("optional").getFirstChild();
186         System.out.println("OPTIONAL FOUND!!!!!!!");
187       } else { optional = false;
188                System.out.println("NOT OPTIONAL");}
189
190       TypeDescriptor type=parseTypeDescriptor(paramn);
191
192       String paramname=paramn.getChild("single").getTerminal();
193       FlagExpressionNode fen=null;
194       if (paramn.getChild("flag")!=null)
195         fen=parseFlagExpression(paramn.getChild("flag").getFirstChild());
196
197       ParseNode tagnode=paramn.getChild("tag");
198
199       TagExpressionList tel=null;
200       if (tagnode!=null) {
201         tel=parseTagExpressionList(tagnode);
202       }
203
204       td.addParameter(type,paramname,fen, tel, optional);
205     }
206   }
207
208   public TagExpressionList parseTagExpressionList(ParseNode pn) {
209     //BUG FIX: change pn.getChildren() to pn.getChild("tag_expression_list").getChildren()
210     //To test, feed in any input program that uses tags
211     ParseNodeVector pnv=pn.getChild("tag_expression_list").getChildren();
212     TagExpressionList tel=new TagExpressionList();
213     for(int i=0; i<pnv.size(); i++) {
214       ParseNode tn=pnv.elementAt(i);
215       String type=tn.getChild("type").getTerminal();
216       String name=tn.getChild("single").getTerminal();
217       tel.addTag(type, name);
218     }
219     return tel;
220   }
221
222   public ClassDescriptor parseTypeDecl(ParseNode pn) {
223     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
224     if (!isEmpty(pn.getChild("super").getTerminal())) {
225       /* parse superclass name */
226       ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
227       NameDescriptor nd=parseName(snn);
228       cn.setSuper(nd.toString());
229     } else {
230       if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
231             cn.getSymbol().equals(TypeUtil.TagClass)))
232         cn.setSuper(TypeUtil.ObjectClass);
233     }
234     cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
235     parseClassBody(cn, pn.getChild("classbody"));
236     return cn;
237   }
238
239   private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
240     ParseNode decls=pn.getChild("class_body_declaration_list");
241     if (decls!=null) {
242       ParseNodeVector pnv=decls.getChildren();
243       for(int i=0; i<pnv.size(); i++) {
244         ParseNode decl=pnv.elementAt(i);
245         if (isNode(decl,"member")) {
246           parseClassMember(cn,decl);
247         } else if (isNode(decl,"constructor")) {
248           parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
249         } else if (isNode(decl,"block")) {
250         } else throw new Error();
251       }
252     }
253   }
254
255   private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
256     ParseNode fieldnode=pn.getChild("field");
257
258     if (fieldnode!=null) {
259       parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
260       return;
261     }
262     ParseNode methodnode=pn.getChild("method");
263     if (methodnode!=null) {
264       parseMethodDecl(cn,methodnode.getChild("method_declaration"));
265       return;
266     }
267     ParseNode flagnode=pn.getChild("flag");
268     if (flagnode!=null) {
269       parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
270       return;
271     }
272     throw new Error();
273   }
274
275   private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
276     ParseNode tn=pn.getChild("type");
277
278     String type_st=tn.getTerminal();
279     if(type_st.equals("byte")) {
280       return state.getTypeDescriptor(TypeDescriptor.BYTE);
281     } else if(type_st.equals("short")) {
282       return state.getTypeDescriptor(TypeDescriptor.SHORT);
283     } else if(type_st.equals("boolean")) {
284       return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
285     } else if(type_st.equals("int")) {
286       return state.getTypeDescriptor(TypeDescriptor.INT);
287     } else if(type_st.equals("long")) {
288       return state.getTypeDescriptor(TypeDescriptor.LONG);
289     } else if(type_st.equals("char")) {
290       return state.getTypeDescriptor(TypeDescriptor.CHAR);
291     } else if(type_st.equals("float")) {
292       return state.getTypeDescriptor(TypeDescriptor.FLOAT);
293     } else if(type_st.equals("double")) {
294       return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
295     } else if(type_st.equals("class")) {
296       ParseNode nn=tn.getChild("class");
297       return state.getTypeDescriptor(parseName(nn.getChild("name")));
298     } else if(type_st.equals("array")) {
299       ParseNode nn=tn.getChild("array");
300       TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
301       Integer numdims=(Integer)nn.getChild("dims").getLiteral();
302       for(int i=0; i<numdims.intValue(); i++)
303         td=td.makeArray(state);
304       return td;
305     } else {
306       throw new Error();
307     }
308   }
309
310   private NameDescriptor parseName(ParseNode nn) {
311     ParseNode base=nn.getChild("base");
312     ParseNode id=nn.getChild("identifier");
313     if (base==null)
314       return new NameDescriptor(id.getTerminal());
315     return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
316
317   }
318
319   private void parseFlagDecl(ClassDescriptor cn,ParseNode pn) {
320     String name=pn.getChild("name").getTerminal();
321     FlagDescriptor flag=new FlagDescriptor(name);
322     if (pn.getChild("external")!=null)
323       flag.makeExternal();
324     cn.addFlag(flag);
325   }
326
327   private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
328     ParseNode mn=pn.getChild("modifier");
329     Modifiers m=parseModifiersList(mn);
330
331     ParseNode tn=pn.getChild("type");
332     TypeDescriptor t=parseTypeDescriptor(tn);
333     ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
334     ParseNodeVector pnv=vn.getChildren();
335     boolean isglobal=pn.getChild("global")!=null;
336
337     for(int i=0; i<pnv.size(); i++) {
338       ParseNode vardecl=pnv.elementAt(i);
339       ParseNode tmp=vardecl;
340       TypeDescriptor arrayt=t;
341       while (tmp.getChild("single")==null) {
342         arrayt=arrayt.makeArray(state);
343         tmp=tmp.getChild("array");
344       }
345       String identifier=tmp.getChild("single").getTerminal();
346       ParseNode epn=vardecl.getChild("initializer");
347
348       ExpressionNode en=null;
349       if (epn!=null)
350         en=parseExpression(epn.getFirstChild());
351
352       cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal));
353     }
354   }
355
356   private ExpressionNode parseExpression(ParseNode pn) {
357     if (isNode(pn,"assignment"))
358       return parseAssignmentExpression(pn);
359     else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
360              isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
361              isNode(pn,"bitwise_and")||isNode(pn,"equal")||
362              isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
363              isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
364              isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
365              isNode(pn,"rightshift")||isNode(pn,"sub")||
366              isNode(pn,"urightshift")||isNode(pn,"sub")||
367              isNode(pn,"add")||isNode(pn,"mult")||
368              isNode(pn,"div")||isNode(pn,"mod")) {
369       ParseNodeVector pnv=pn.getChildren();
370       ParseNode left=pnv.elementAt(0);
371       ParseNode right=pnv.elementAt(1);
372       Operation op=new Operation(pn.getLabel());
373       return new OpNode(parseExpression(left),parseExpression(right),op);
374     } else if (isNode(pn,"unaryplus")||
375                isNode(pn,"unaryminus")||
376                isNode(pn,"not")||
377                isNode(pn,"comp")) {
378       ParseNode left=pn.getFirstChild();
379       Operation op=new Operation(pn.getLabel());
380       return new OpNode(parseExpression(left),op);
381     } else if (isNode(pn,"postinc")||
382                isNode(pn,"postdec")) {
383       ParseNode left=pn.getFirstChild();
384       AssignOperation op=new AssignOperation(pn.getLabel());
385       return new AssignmentNode(parseExpression(left),null,op);
386
387     } else if (isNode(pn,"preinc")||
388                isNode(pn,"predec")) {
389       ParseNode left=pn.getFirstChild();
390       AssignOperation op=isNode(pn,"preinc") ? new AssignOperation(AssignOperation.PLUSEQ) : new AssignOperation(AssignOperation.MINUSEQ);
391       return new AssignmentNode(parseExpression(left),
392                                 new LiteralNode("integer",new Integer(1)),op);
393     } else if (isNode(pn,"literal")) {
394       String literaltype=pn.getTerminal();
395       ParseNode literalnode=pn.getChild(literaltype);
396       Object literal_obj=literalnode.getLiteral();
397       return new LiteralNode(literaltype, literal_obj);
398     } else if (isNode(pn,"createobject")) {
399       TypeDescriptor td=parseTypeDescriptor(pn);
400       Vector args=parseArgumentList(pn);
401       boolean isglobal=pn.getChild("global")!=null;
402       CreateObjectNode con=new CreateObjectNode(td, isglobal);
403       for(int i=0; i<args.size(); i++) {
404         con.addArgument((ExpressionNode)args.get(i));
405       }
406       /* Could have flag set or tag added here */
407       if (pn.getChild("flag_list")!=null||pn.getChild("tag_list")!=null) {
408         FlagEffects fe=new FlagEffects(null);
409         if (pn.getChild("flag_list")!=null)
410           parseFlagEffect(fe, pn.getChild("flag_list"));
411
412         if (pn.getChild("tag_list")!=null)
413           parseTagEffect(fe, pn.getChild("tag_list"));
414         con.addFlagEffects(fe);
415       }
416
417       return con;
418     } else if (isNode(pn,"createarray")) {
419       //System.out.println(pn.PPrint(3,true));
420       boolean isglobal=pn.getChild("global")!=null;
421       TypeDescriptor td=parseTypeDescriptor(pn);
422       Vector args=parseDimExprs(pn);
423       int num=0;
424       if (pn.getChild("dims_opt").getLiteral()!=null)
425         num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
426       for(int i=0; i<(args.size()+num); i++)
427         td=td.makeArray(state);
428       CreateObjectNode con=new CreateObjectNode(td, isglobal);
429       for(int i=0; i<args.size(); i++) {
430         con.addArgument((ExpressionNode)args.get(i));
431       }
432       return con;
433     } else if (isNode(pn,"name")) {
434       NameDescriptor nd=parseName(pn);
435       return new NameNode(nd);
436     } else if (isNode(pn,"this")) {
437       NameDescriptor nd=new NameDescriptor("this");
438       return new NameNode(nd);
439     } else if (isNode(pn,"isavailable")) {
440       NameDescriptor nd=new NameDescriptor(pn.getTerminal());
441       return new OpNode(new NameNode(nd),null,new Operation(Operation.ISAVAILABLE));
442     } else if (isNode(pn,"methodinvoke1")) {
443       NameDescriptor nd=parseName(pn.getChild("name"));
444       Vector args=parseArgumentList(pn);
445       MethodInvokeNode min=new MethodInvokeNode(nd);
446       for(int i=0; i<args.size(); i++) {
447         min.addArgument((ExpressionNode)args.get(i));
448       }
449       return min;
450     } else if (isNode(pn,"methodinvoke2")) {
451       String methodid=pn.getChild("id").getTerminal();
452       ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
453       Vector args=parseArgumentList(pn);
454       MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
455       for(int i=0; i<args.size(); i++) {
456         min.addArgument((ExpressionNode)args.get(i));
457       }
458       return min;
459     } else if (isNode(pn,"fieldaccess")) {
460       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());          String fieldname=pn.getChild("field").getTerminal();
461       return new FieldAccessNode(en,fieldname);
462     } else if (isNode(pn,"arrayaccess")) {
463       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
464       ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
465       return new ArrayAccessNode(en,index);
466     } else if (isNode(pn,"cast1")) {
467       return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
468     } else if (isNode(pn,"cast2")) {
469       return new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
470     } else {
471       System.out.println("---------------------");
472       System.out.println(pn.PPrint(3,true));
473       throw new Error();
474     }
475   }
476
477   private Vector parseDimExprs(ParseNode pn) {
478     Vector arglist=new Vector();
479     ParseNode an=pn.getChild("dim_exprs");
480     if (an==null)       /* No argument list */
481       return arglist;
482     ParseNodeVector anv=an.getChildren();
483     for(int i=0; i<anv.size(); i++) {
484       arglist.add(parseExpression(anv.elementAt(i)));
485     }
486     return arglist;
487   }
488
489   private Vector parseArgumentList(ParseNode pn) {
490     Vector arglist=new Vector();
491     ParseNode an=pn.getChild("argument_list");
492     if (an==null)       /* No argument list */
493       return arglist;
494     ParseNodeVector anv=an.getChildren();
495     for(int i=0; i<anv.size(); i++) {
496       arglist.add(parseExpression(anv.elementAt(i)));
497     }
498     return arglist;
499   }
500
501   private Vector[] parseConsArgumentList(ParseNode pn) {
502     Vector arglist=new Vector();
503     Vector varlist=new Vector();
504     ParseNode an=pn.getChild("cons_argument_list");
505     if (an==null)       /* No argument list */
506       return new Vector[] {varlist, arglist};
507     ParseNodeVector anv=an.getChildren();
508     for(int i=0; i<anv.size(); i++) {
509       ParseNode cpn=anv.elementAt(i);
510       ParseNode var=cpn.getChild("var");
511       ParseNode exp=cpn.getChild("exp").getFirstChild();
512       varlist.add(var.getTerminal());
513       arglist.add(parseExpression(exp));
514     }
515     return new Vector[] {varlist, arglist};
516   }
517
518   private ExpressionNode parseAssignmentExpression(ParseNode pn) {
519     AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
520     ParseNodeVector pnv=pn.getChild("args").getChildren();
521
522     AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
523     return an;
524   }
525
526
527   private void parseMethodDecl(ClassDescriptor cn, ParseNode pn) {
528     ParseNode headern=pn.getChild("method_header");
529     ParseNode bodyn=pn.getChild("body");
530     MethodDescriptor md=parseMethodHeader(headern);
531     BlockNode bn=parseBlock(bodyn);
532     cn.addMethod(md);
533     state.addTreeCode(md,bn);
534   }
535
536   private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
537     ParseNode mn=pn.getChild("modifiers");
538     Modifiers m=parseModifiersList(mn);
539     ParseNode cdecl=pn.getChild("constructor_declarator");
540     boolean isglobal=cdecl.getChild("global")!=null;
541     String name=cdecl.getChild("name").getChild("identifier").getTerminal();
542     MethodDescriptor md=new MethodDescriptor(m, name, isglobal);
543     ParseNode paramnode=cdecl.getChild("parameters");
544     parseParameterList(md,paramnode);
545     ParseNode bodyn0=pn.getChild("body");
546     ParseNode bodyn=bodyn0.getChild("constructor_body");
547     cn.addMethod(md);
548     BlockNode bn=null;
549     if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
550       bn=parseBlock(bodyn);
551     else
552       bn=new BlockNode();
553     if (bodyn!=null&&bodyn.getChild("superinvoke")!=null) {
554       ParseNode sin=bodyn.getChild("superinvoke");
555       NameDescriptor nd=new NameDescriptor("super");
556       Vector args=parseArgumentList(sin);
557       MethodInvokeNode min=new MethodInvokeNode(nd);
558       for(int i=0; i<args.size(); i++) {
559         min.addArgument((ExpressionNode)args.get(i));
560       }
561       BlockExpressionNode ben=new BlockExpressionNode(min);
562       bn.addFirstBlockStatement(ben);
563     }
564     state.addTreeCode(md,bn);
565   }
566
567   public BlockNode parseBlock(ParseNode pn) {
568       this.m_taskexitnum = 0;
569     if (pn==null||isEmpty(pn.getTerminal()))
570       return new BlockNode();
571     ParseNode bsn=pn.getChild("block_statement_list");
572     return parseBlockHelper(bsn);
573   }
574
575   private BlockNode parseBlockHelper(ParseNode pn) {
576     ParseNodeVector pnv=pn.getChildren();
577     BlockNode bn=new BlockNode();
578     for(int i=0; i<pnv.size(); i++) {
579       Vector bsv=parseBlockStatement(pnv.elementAt(i));
580       for(int j=0; j<bsv.size(); j++) {
581         bn.addBlockStatement((BlockStatementNode)bsv.get(j));
582       }
583     }
584     return bn;
585   }
586
587   public BlockNode parseSingleBlock(ParseNode pn) {
588     BlockNode bn=new BlockNode();
589     Vector bsv=parseBlockStatement(pn);
590     for(int j=0; j<bsv.size(); j++) {
591       bn.addBlockStatement((BlockStatementNode)bsv.get(j));
592     }
593     bn.setStyle(BlockNode.NOBRACES);
594     return bn;
595   }
596
597   public Vector parseBlockStatement(ParseNode pn) {
598     Vector blockstatements=new Vector();
599     if (isNode(pn,"tag_declaration")) {
600       String name=pn.getChild("single").getTerminal();
601       String type=pn.getChild("type").getTerminal();
602
603       blockstatements.add(new TagDeclarationNode(name, type));
604     } else if (isNode(pn,"local_variable_declaration")) {
605       TypeDescriptor t=parseTypeDescriptor(pn);
606       ParseNode vn=pn.getChild("variable_declarators_list");
607       ParseNodeVector pnv=vn.getChildren();
608       for(int i=0; i<pnv.size(); i++) {
609         ParseNode vardecl=pnv.elementAt(i);
610
611
612         ParseNode tmp=vardecl;
613         TypeDescriptor arrayt=t;
614         while (tmp.getChild("single")==null) {
615           arrayt=arrayt.makeArray(state);
616           tmp=tmp.getChild("array");
617         }
618         String identifier=tmp.getChild("single").getTerminal();
619
620         ParseNode epn=vardecl.getChild("initializer");
621
622
623         ExpressionNode en=null;
624         if (epn!=null)
625           en=parseExpression(epn.getFirstChild());
626
627         blockstatements.add(new DeclarationNode(new VarDescriptor(arrayt, identifier),en));
628       }
629     } else if (isNode(pn,"nop")) {
630       /* Do Nothing */
631     } else if (isNode(pn,"expression")) {
632       blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
633     } else if (isNode(pn,"ifstatement")) {
634       blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
635                                               parseSingleBlock(pn.getChild("statement").getFirstChild()),
636                                               pn.getChild("else_statement")!=null ? parseSingleBlock(pn.getChild("else_statement").getFirstChild()) : null));
637     } else if (isNode(pn,"taskexit")) {
638       Vector vfe=null;
639       if (pn.getChild("flag_effects_list")!=null)
640         vfe=parseFlags(pn.getChild("flag_effects_list"));
641       Vector ccs=null;
642       if (pn.getChild("cons_checks")!=null)
643         ccs=parseChecks(pn.getChild("cons_checks"));
644
645       blockstatements.add(new TaskExitNode(vfe, ccs, this.m_taskexitnum++));
646     } else if (isNode(pn,"atomic")) {
647       BlockNode bn=parseBlockHelper(pn);
648       blockstatements.add(new AtomicNode(bn));
649     } else if (isNode(pn,"return")) {
650       if (isEmpty(pn.getTerminal()))
651         blockstatements.add(new ReturnNode());
652       else {
653         ExpressionNode en=parseExpression(pn.getFirstChild());
654         blockstatements.add(new ReturnNode(en));
655       }
656     } else if (isNode(pn,"block_statement_list")) {
657       BlockNode bn=parseBlockHelper(pn);
658       blockstatements.add(new SubBlockNode(bn));
659     } else if (isNode(pn,"empty")) {
660       /* nop */
661     } else if (isNode(pn,"statement_expression_list")) {
662       ParseNodeVector pnv=pn.getChildren();
663       BlockNode bn=new BlockNode();
664       for(int i=0; i<pnv.size(); i++) {
665         ExpressionNode en=parseExpression(pnv.elementAt(i));
666         blockstatements.add(new BlockExpressionNode(en));
667       }
668       bn.setStyle(BlockNode.EXPRLIST);
669     } else if (isNode(pn,"forstatement")) {
670       BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
671       BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
672       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
673       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
674       blockstatements.add(new LoopNode(init,condition,update,body));
675     } else if (isNode(pn,"whilestatement")) {
676       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
677       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
678       blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
679     } else if (isNode(pn,"dowhilestatement")) {
680       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
681       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
682       blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
683     } else {
684       System.out.println("---------------");
685       System.out.println(pn.PPrint(3,true));
686       throw new Error();
687     }
688     return blockstatements;
689   }
690
691   public MethodDescriptor parseMethodHeader(ParseNode pn) {
692     ParseNode mn=pn.getChild("modifiers");
693     Modifiers m=parseModifiersList(mn);
694
695     ParseNode tn=pn.getChild("returntype");
696     TypeDescriptor returntype;
697     if (tn!=null)
698       returntype=parseTypeDescriptor(tn);
699     else
700       returntype=new TypeDescriptor(TypeDescriptor.VOID);
701
702     ParseNode pmd=pn.getChild("method_declarator");
703     String name=pmd.getChild("name").getTerminal();
704     MethodDescriptor md=new MethodDescriptor(m, returntype, name);
705
706     ParseNode paramnode=pmd.getChild("parameters");
707     parseParameterList(md,paramnode);
708     return md;
709   }
710
711   public void parseParameterList(MethodDescriptor md, ParseNode pn) {
712     ParseNode paramlist=pn.getChild("formal_parameter_list");
713     if (paramlist==null)
714       return;
715     ParseNodeVector pnv=paramlist.getChildren();
716     for(int i=0; i<pnv.size(); i++) {
717       ParseNode paramn=pnv.elementAt(i);
718
719       if (isNode(paramn, "tag_parameter")) {
720         String paramname=paramn.getChild("single").getTerminal();
721         TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
722         md.addTagParameter(type, paramname);
723       } else {
724         TypeDescriptor type=parseTypeDescriptor(paramn);
725
726         ParseNode tmp=paramn;
727         while (tmp.getChild("single")==null) {
728           type=type.makeArray(state);
729           tmp=tmp.getChild("array");
730         }
731         String paramname=tmp.getChild("single").getTerminal();
732
733         md.addParameter(type, paramname);
734       }
735     }
736   }
737
738   public Modifiers parseModifiersList(ParseNode pn) {
739     Modifiers m=new Modifiers();
740     ParseNode modlist=pn.getChild("modifier_list");
741     if (modlist!=null) {
742       ParseNodeVector pnv=modlist.getChildren();
743       for(int i=0; i<pnv.size(); i++) {
744         ParseNode modn=pnv.elementAt(i);
745         if (isNode(modn,"public"))
746           m.addModifier(Modifiers.PUBLIC);
747         else if (isNode(modn,"protected"))
748           m.addModifier(Modifiers.PROTECTED);
749         else if (isNode(modn,"private"))
750           m.addModifier(Modifiers.PRIVATE);
751         else if (isNode(modn,"static"))
752           m.addModifier(Modifiers.STATIC);
753         else if (isNode(modn,"final"))
754           m.addModifier(Modifiers.FINAL);
755         else if (isNode(modn,"native"))
756           m.addModifier(Modifiers.NATIVE);
757         else if (isNode(modn,"synchronized"))
758           m.addModifier(Modifiers.SYNCHRONIZED);
759         else if (isNode(modn,"atomic"))
760           m.addModifier(Modifiers.ATOMIC);
761         else throw new Error("Unrecognized Modifier");
762       }
763     }
764     return m;
765   }
766
767   private boolean isNode(ParseNode pn, String label) {
768     if (pn.getLabel().equals(label))
769       return true;
770     else return false;
771   }
772
773   private static boolean isEmpty(ParseNode pn) {
774     if (pn.getLabel().equals("empty"))
775       return true;
776     else
777       return false;
778   }
779
780   private static boolean isEmpty(String s) {
781     if (s.equals("empty"))
782       return true;
783     else
784       return false;
785   }
786
787   /** Throw an exception if something is unexpected */
788   private void check(ParseNode pn, String label) {
789     if (pn == null) {
790       throw new Error(pn+ "IE: Expected '" + label + "', got null");
791     }
792     if (!pn.getLabel().equals(label)) {
793       throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
794     }
795   }
796 }