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