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