9 private int m_taskexitnum;
11 public BuildIR(State state) {
13 this.m_taskexitnum = 0;
16 public void buildtree(ParseNode pn, Set toanalyze, String sourcefile) {
17 parseFile(pn, toanalyze, sourcefile);
19 // numering the interfaces
21 Iterator it_classes = state.getClassSymbolTable().getValueSet().iterator();
22 while(it_classes.hasNext()) {
23 ClassDescriptor cd = (ClassDescriptor)it_classes.next();
24 if(cd.isInterface()) {
25 cd.setInterfaceId(if_num++);
30 Hashtable singleimports;
32 NameDescriptor packages;
34 /** Parse the classes in this file */
35 public void parseFile(ParseNode pn, Set toanalyze, String sourcefile) {
36 singleimports=new Hashtable();
37 multiimports=new Vector();
38 ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
40 ParseNodeVector pnv=ipn.getChildren();
41 for(int i=0; i<pnv.size(); i++) {
42 ParseNode pnimport=pnv.elementAt(i);
43 NameDescriptor nd=parseName(pnimport.getChild("name"));
44 // TODO need to implement
45 if (isNode(pnimport,"import_single"))
46 if(!singleimports.containsKey(nd.getIdentifier())) {
47 //map name to full name (includes package/directory
48 singleimports.put(nd.getIdentifier(), nd.getPathFromRootToHere(nd.getIdentifier()));
50 throw new Error("Error: class " + nd.getIdentifier() + " is already more than once in a single type import inside "+sourcefile);
60 ParseNode ppn=pn.getChild("packages").getChild("package");
61 String packageName = null;
63 packageName = ppn.getChild("name").getChild("identifier").getTerminal();
65 ParseNode tpn=pn.getChild("type_declaration_list");
67 ParseNodeVector pnv = tpn.getChildren();
68 for (int i = 0; i < pnv.size(); i++) {
69 ParseNode type_pn = pnv.elementAt(i);
70 if (isEmpty(type_pn)) /* Skip the semicolon */
72 if (isNode(type_pn, "class_declaration")) {
73 ClassDescriptor cn = parseTypeDecl(type_pn, packageName);
74 cn.setSourceFileName(sourcefile);
75 parseInitializers(cn);
76 if (toanalyze != null)
79 // for inner classes/enum
80 HashSet tovisit = new HashSet();
81 Iterator it_icds = cn.getInnerClasses();
82 while (it_icds.hasNext()) {
83 tovisit.add(it_icds.next());
86 while (!tovisit.isEmpty()) {
87 ClassDescriptor cd = (ClassDescriptor) tovisit.iterator().next();
89 parseInitializers(cd);
90 if (toanalyze != null) {
93 cd.setSourceFileName(sourcefile);
96 Iterator it_ics = cd.getInnerClasses();
97 while (it_ics.hasNext()) {
98 tovisit.add(it_ics.next());
101 Iterator it_ienums = cd.getEnum();
102 while (it_ienums.hasNext()) {
103 ClassDescriptor iecd = (ClassDescriptor) it_ienums.next();
104 if (toanalyze != null) {
107 iecd.setSourceFileName(sourcefile);
108 state.addClass(iecd);
112 Iterator it_enums = cn.getEnum();
113 while (it_enums.hasNext()) {
114 ClassDescriptor ecd = (ClassDescriptor) it_enums.next();
115 if (toanalyze != null) {
118 ecd.setSourceFileName(sourcefile);
121 } else if (isNode(type_pn, "task_declaration")) {
122 TaskDescriptor td = parseTaskDecl(type_pn);
123 if (toanalyze != null)
126 } else if (isNode(type_pn, "interface_declaration")) {
127 // TODO add version for normal Java later
128 ClassDescriptor cn = parseInterfaceDecl(type_pn);
129 if (toanalyze != null)
131 cn.setSourceFileName(sourcefile);
135 Iterator it_enums = cn.getEnum();
136 while (it_enums.hasNext()) {
137 ClassDescriptor ecd = (ClassDescriptor) it_enums.next();
138 if (toanalyze != null) {
141 ecd.setSourceFileName(sourcefile);
144 } else if (isNode(type_pn, "enum_declaration")) {
145 // TODO add version for normal Java later
146 ClassDescriptor cn = parseEnumDecl(null, type_pn);
147 if (toanalyze != null)
149 cn.setSourceFileName(sourcefile);
152 throw new Error(type_pn.getLabel());
158 public void parseInitializers(ClassDescriptor cn){
159 Vector fv=cn.getFieldVec();
161 for(int i=0;i<fv.size();i++) {
162 FieldDescriptor fd=(FieldDescriptor)fv.get(i);
163 if(fd.getExpressionNode()!=null) {
164 Iterator methodit = cn.getMethods();
165 while(methodit.hasNext()){
166 MethodDescriptor currmd=(MethodDescriptor)methodit.next();
167 if(currmd.isConstructor()){
168 BlockNode bn=state.getMethodBody(currmd);
169 NameNode nn=new NameNode(new NameDescriptor(fd.getSymbol()));
170 AssignmentNode an=new AssignmentNode(nn,fd.getExpressionNode(),new AssignOperation(1));
171 bn.addBlockStatementAt(new BlockExpressionNode(an), pos);
179 private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
180 ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
181 ecd.setImports(singleimports, multiimports);
184 ecd.setSurroundingClass(cn.getSymbol());
185 ecd.setSurrounding(cn);
188 if (!(ecd.getSymbol().equals(TypeUtil.ObjectClass)||
189 ecd.getSymbol().equals(TypeUtil.TagClass))) {
190 ecd.setSuper(TypeUtil.ObjectClass);
192 ecd.setModifiers(parseModifiersList(pn.getChild("modifiers")));
193 parseEnumBody(ecd, pn.getChild("enumbody"));
197 private void parseEnumBody(ClassDescriptor cn, ParseNode pn) {
198 ParseNode decls=pn.getChild("enum_constants_list");
200 ParseNodeVector pnv=decls.getChildren();
201 for(int i=0; i<pnv.size(); i++) {
202 ParseNode decl=pnv.elementAt(i);
203 if (isNode(decl,"enum_constant")) {
204 parseEnumConstant(cn,decl);
205 } else throw new Error();
210 private void parseEnumConstant(ClassDescriptor cn, ParseNode pn) {
211 cn.addEnumConstant(pn.getChild("name").getTerminal());
214 public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
215 ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
216 cn.setImports(singleimports, multiimports);
217 //cn.setAsInterface();
218 if (!isEmpty(pn.getChild("superIF").getTerminal())) {
219 /* parse inherited interface name */
220 ParseNode snlist=pn.getChild("superIF").getChild("extend_interface_list");
221 ParseNodeVector pnv=snlist.getChildren();
222 for(int i=0; i<pnv.size(); i++) {
223 ParseNode decl=pnv.elementAt(i);
224 if (isNode(decl,"type")) {
225 NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
226 cn.addSuperInterface(nd.toString());
230 cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
231 parseInterfaceBody(cn, pn.getChild("interfacebody"));
235 private void parseInterfaceBody(ClassDescriptor cn, ParseNode pn) {
236 assert(cn.isInterface());
237 ParseNode decls=pn.getChild("interface_member_declaration_list");
239 ParseNodeVector pnv=decls.getChildren();
240 for(int i=0; i<pnv.size(); i++) {
241 ParseNode decl=pnv.elementAt(i);
242 if (isNode(decl,"constant")) {
243 parseInterfaceConstant(cn,decl);
244 } else if (isNode(decl,"method")) {
245 parseInterfaceMethod(cn,decl.getChild("method_declaration"));
246 } else throw new Error();
251 private void parseInterfaceConstant(ClassDescriptor cn, ParseNode pn) {
253 parseFieldDecl(cn,pn.getChild("field_declaration"));
259 private void parseInterfaceMethod(ClassDescriptor cn, ParseNode pn) {
260 ParseNode headern=pn.getChild("header");
261 ParseNode bodyn=pn.getChild("body");
262 MethodDescriptor md=parseMethodHeader(headern.getChild("method_header"));
263 md.getModifiers().addModifier(Modifiers.PUBLIC);
264 md.getModifiers().addModifier(Modifiers.ABSTRACT);
266 BlockNode bn=parseBlock(bodyn);
268 state.addTreeCode(md,bn);
270 // this is a hack for investigating new language features
271 // at the AST level, someday should evolve into a nice compiler
273 //if( cn.getSymbol().equals( ***put a class in here like: "Test" ) &&
274 // md.getSymbol().equals( ***put your method in here like: "main" )
276 // bn.setStyle( BlockNode.NORMAL );
277 // System.out.println( bn.printNode( 0 ) );
280 } catch (Exception e) {
281 System.out.println("Error with method:"+md.getSymbol());
285 System.out.println("Error with method:"+md.getSymbol());
291 public TaskDescriptor parseTaskDecl(ParseNode pn) {
292 TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
293 ParseNode bodyn=pn.getChild("body");
294 BlockNode bn=parseBlock(bodyn);
295 parseParameterList(td, pn);
296 state.addTreeCode(td,bn);
297 if (pn.getChild("flag_effects_list")!=null)
298 td.addFlagEffects(parseFlags(pn.getChild("flag_effects_list")));
302 public Vector parseFlags(ParseNode pn) {
303 Vector vfe=new Vector();
304 ParseNodeVector pnv=pn.getChildren();
305 for(int i=0; i<pnv.size(); i++) {
306 ParseNode fn=pnv.elementAt(i);
307 FlagEffects fe=parseFlagEffects(fn);
313 public FlagEffects parseFlagEffects(ParseNode pn) {
314 if (isNode(pn,"flag_effect")) {
315 String flagname=pn.getChild("name").getTerminal();
316 FlagEffects fe=new FlagEffects(flagname);
317 if (pn.getChild("flag_list")!=null)
318 parseFlagEffect(fe, pn.getChild("flag_list"));
319 if (pn.getChild("tag_list")!=null)
320 parseTagEffect(fe, pn.getChild("tag_list"));
322 } else throw new Error();
325 public void parseTagEffect(FlagEffects fes, ParseNode pn) {
326 ParseNodeVector pnv=pn.getChildren();
327 for(int i=0; i<pnv.size(); i++) {
328 ParseNode pn2=pnv.elementAt(i);
330 if (isNode(pn2,"not")) {
332 pn2=pn2.getChild("name");
334 String name=pn2.getTerminal();
335 fes.addTagEffect(new TagEffect(name,status));
339 public void parseFlagEffect(FlagEffects fes, ParseNode pn) {
340 ParseNodeVector pnv=pn.getChildren();
341 for(int i=0; i<pnv.size(); i++) {
342 ParseNode pn2=pnv.elementAt(i);
344 if (isNode(pn2,"not")) {
346 pn2=pn2.getChild("name");
348 String name=pn2.getTerminal();
349 fes.addEffect(new FlagEffect(name,status));
353 public FlagExpressionNode parseFlagExpression(ParseNode pn) {
354 if (isNode(pn,"or")) {
355 ParseNodeVector pnv=pn.getChildren();
356 ParseNode left=pnv.elementAt(0);
357 ParseNode right=pnv.elementAt(1);
358 return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_OR));
359 } else if (isNode(pn,"and")) {
360 ParseNodeVector pnv=pn.getChildren();
361 ParseNode left=pnv.elementAt(0);
362 ParseNode right=pnv.elementAt(1);
363 return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_AND));
364 } else if (isNode(pn, "not")) {
365 ParseNodeVector pnv=pn.getChildren();
366 ParseNode left=pnv.elementAt(0);
367 return new FlagOpNode(parseFlagExpression(left), new Operation(Operation.LOGIC_NOT));
369 } else if (isNode(pn,"name")) {
370 return new FlagNode(pn.getTerminal());
376 public Vector parseChecks(ParseNode pn) {
377 Vector ccs=new Vector();
378 ParseNodeVector pnv=pn.getChildren();
379 for(int i=0; i<pnv.size(); i++) {
380 ParseNode fn=pnv.elementAt(i);
381 ConstraintCheck cc=parseConstraintCheck(fn);
387 public ConstraintCheck parseConstraintCheck(ParseNode pn) {
388 if (isNode(pn,"cons_check")) {
389 String specname=pn.getChild("name").getChild("identifier").getTerminal();
390 Vector[] args=parseConsArgumentList(pn);
391 ConstraintCheck cc=new ConstraintCheck(specname);
392 for(int i=0; i<args[0].size(); i++) {
393 cc.addVariable((String)args[0].get(i));
394 cc.addArgument((ExpressionNode)args[1].get(i));
397 } else throw new Error();
400 public void parseParameterList(TaskDescriptor td, ParseNode pn) {
403 ParseNode paramlist=pn.getChild("task_parameter_list");
406 ParseNodeVector pnv=paramlist.getChildren();
407 for(int i=0; i<pnv.size(); i++) {
408 ParseNode paramn=pnv.elementAt(i);
409 if(paramn.getChild("optional")!=null) {
411 paramn = paramn.getChild("optional").getFirstChild();
412 System.out.println("OPTIONAL FOUND!!!!!!!");
413 } else { optional = false;
414 System.out.println("NOT OPTIONAL");}
416 TypeDescriptor type=parseTypeDescriptor(paramn);
418 String paramname=paramn.getChild("single").getTerminal();
419 FlagExpressionNode fen=null;
420 if (paramn.getChild("flag")!=null)
421 fen=parseFlagExpression(paramn.getChild("flag").getFirstChild());
423 ParseNode tagnode=paramn.getChild("tag");
425 TagExpressionList tel=null;
427 tel=parseTagExpressionList(tagnode);
430 td.addParameter(type,paramname,fen, tel, optional);
434 public TagExpressionList parseTagExpressionList(ParseNode pn) {
435 //BUG FIX: change pn.getChildren() to pn.getChild("tag_expression_list").getChildren()
436 //To test, feed in any input program that uses tags
437 ParseNodeVector pnv=pn.getChild("tag_expression_list").getChildren();
438 TagExpressionList tel=new TagExpressionList();
439 for(int i=0; i<pnv.size(); i++) {
440 ParseNode tn=pnv.elementAt(i);
441 String type=tn.getChild("type").getTerminal();
442 String name=tn.getChild("single").getTerminal();
443 tel.addTag(type, name);
448 public ClassDescriptor parseTypeDecl(ParseNode pn, String packageName) {
450 // if is in no package, then create a class descriptor with just the name.
451 // else add the package on and replace "." with "___________"
452 if(packageName == null) {
453 cn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
455 String newClassname = packageName + "___________" + pn.getChild("name").getTerminal();
456 cn= new ClassDescriptor(packageName, newClassname.replaceAll("\\.", "___________") , false);
458 cn.setImports(singleimports, multiimports);
459 if (!isEmpty(pn.getChild("super").getTerminal())) {
460 /* parse superclass name */
461 ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
462 NameDescriptor nd=parseName(snn);
463 cn.setSuper(nd.toString());
465 if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
466 cn.getSymbol().equals(TypeUtil.TagClass)))
467 cn.setSuper(TypeUtil.ObjectClass);
469 // check inherited interfaces
470 if (!isEmpty(pn.getChild("superIF").getTerminal())) {
471 /* parse inherited interface name */
472 ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list");
473 ParseNodeVector pnv=snlist.getChildren();
474 for(int i=0; i<pnv.size(); i++) {
475 ParseNode decl=pnv.elementAt(i);
476 if (isNode(decl,"type")) {
477 NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
478 cn.addSuperInterface(nd.toString());
482 cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
483 parseClassBody(cn, pn.getChild("classbody"));
485 boolean hasConstructor = false;
486 for(Iterator method_it=cn.getMethods(); method_it.hasNext();) {
487 MethodDescriptor md=(MethodDescriptor)method_it.next();
488 hasConstructor |= md.isConstructor();
490 if((!hasConstructor) && (!cn.isEnum())) {
491 // add a default constructor for this class
492 MethodDescriptor md = new MethodDescriptor(new Modifiers(Modifiers.PUBLIC),
493 cn.getSymbol(), false);
494 BlockNode bn=new BlockNode();
495 state.addTreeCode(md,bn);
496 md.setDefaultConstructor();
502 private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
503 ParseNode decls=pn.getChild("class_body_declaration_list");
505 ParseNodeVector pnv=decls.getChildren();
506 for(int i=0; i<pnv.size(); i++) {
507 ParseNode decl=pnv.elementAt(i);
508 if (isNode(decl,"member")) {
509 parseClassMember(cn,decl);
510 } else if (isNode(decl,"constructor")) {
511 parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
512 } else if (isNode(decl, "static_block")) {
513 parseStaticBlockDecl(cn, decl.getChild("static_block_declaration"));
514 } else if (isNode(decl,"block")) {
515 } else if (isNode(decl,"location_order_declaration")) {
516 parseLocationOrder(cn,decl.getChild("location_order_list"));
517 } else throw new Error();
522 private void parseLocationOrder(ClassDescriptor cd, ParseNode pn) {
523 ParseNodeVector pnv = pn.getChildren();
524 Lattice<String> locOrder =
525 new Lattice<String>("_top_","_bottom_");
526 Set<String> spinLocSet=new HashSet<String>();
527 for (int i = 0; i < pnv.size(); i++) {
528 ParseNode loc = pnv.elementAt(i);
529 if(isNode(loc,"location_property")){
530 String spinLoc=loc.getChildren().elementAt(0).getLabel();
531 spinLocSet.add(spinLoc);
533 String lowerLoc=loc.getChildren().elementAt(0).getLabel();
534 String higherLoc= loc.getChildren().elementAt(1).getLabel();
535 locOrder.put(higherLoc, lowerLoc);
536 if (locOrder.isIntroducingCycle(higherLoc)) {
537 throw new Error("Error: the order relation " + lowerLoc + " < " + higherLoc
538 + " introduces a cycle.");
542 if(spinLocSet.size()>0){
543 //checking if location is actually defined in the hierarchy
544 for (Iterator iterator = spinLocSet.iterator(); iterator.hasNext();) {
545 String locID = (String) iterator.next();
546 if(!locOrder.containsKey(locID)){
547 throw new Error("Error: The spinning location '"+
548 locID + "' is not defined in the hierarchy of the class '"+cd +"'.");
551 state.addLocationPropertySet(cd, spinLocSet);
553 state.addLocationOrder(cd, locOrder);
556 private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
557 ParseNode fieldnode=pn.getChild("field");
558 if (fieldnode!=null) {
559 parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
562 ParseNode methodnode=pn.getChild("method");
563 if (methodnode!=null) {
564 parseMethodDecl(cn,methodnode.getChild("method_declaration"));
567 ParseNode innerclassnode=pn.getChild("inner_class_declaration");
568 if (innerclassnode!=null) {
569 parseInnerClassDecl(cn,innerclassnode);
572 ParseNode enumnode=pn.getChild("enum_declaration");
573 if (enumnode!=null) {
574 parseEnumDecl(cn,enumnode);
577 ParseNode flagnode=pn.getChild("flag");
578 if (flagnode!=null) {
579 parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
582 // in case there are empty node
583 ParseNode emptynode=pn.getChild("empty");
584 if(emptynode != null) {
590 private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) {
591 ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
592 icn.setImports(singleimports, multiimports);
593 icn.setAsInnerClass();
594 icn.setSurroundingClass(cn.getSymbol());
595 icn.setSurrounding(cn);
596 cn.addInnerClass(icn);
597 if (!isEmpty(pn.getChild("super").getTerminal())) {
598 /* parse superclass name */
599 ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
600 NameDescriptor nd=parseName(snn);
601 icn.setSuper(nd.toString());
603 if (!(icn.getSymbol().equals(TypeUtil.ObjectClass)||
604 icn.getSymbol().equals(TypeUtil.TagClass)))
605 icn.setSuper(TypeUtil.ObjectClass);
607 // check inherited interfaces
608 if (!isEmpty(pn.getChild("superIF").getTerminal())) {
609 /* parse inherited interface name */
610 ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list");
611 ParseNodeVector pnv=snlist.getChildren();
612 for(int i=0; i<pnv.size(); i++) {
613 ParseNode decl=pnv.elementAt(i);
614 if (isNode(decl,"type")) {
615 NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
616 icn.addSuperInterface(nd.toString());
620 icn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
621 if(!icn.isStatic()) {
622 throw new Error("Error: inner class " + icn.getSymbol() + " in Class " +
623 cn.getSymbol() + " is not a nested class and is not supported yet!");
625 parseClassBody(icn, pn.getChild("classbody"));
629 private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
630 ParseNode tn=pn.getChild("type");
631 String type_st=tn.getTerminal();
632 if(type_st.equals("byte")) {
633 return state.getTypeDescriptor(TypeDescriptor.BYTE);
634 } else if(type_st.equals("short")) {
635 return state.getTypeDescriptor(TypeDescriptor.SHORT);
636 } else if(type_st.equals("boolean")) {
637 return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
638 } else if(type_st.equals("int")) {
639 return state.getTypeDescriptor(TypeDescriptor.INT);
640 } else if(type_st.equals("long")) {
641 return state.getTypeDescriptor(TypeDescriptor.LONG);
642 } else if(type_st.equals("char")) {
643 return state.getTypeDescriptor(TypeDescriptor.CHAR);
644 } else if(type_st.equals("float")) {
645 return state.getTypeDescriptor(TypeDescriptor.FLOAT);
646 } else if(type_st.equals("double")) {
647 return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
648 } else if(type_st.equals("class")) {
649 ParseNode nn=tn.getChild("class");
650 return state.getTypeDescriptor(parseName(nn.getChild("name")));
651 } else if(type_st.equals("array")) {
652 ParseNode nn=tn.getChild("array");
653 TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
654 Integer numdims=(Integer)nn.getChild("dims").getLiteral();
655 for(int i=0; i<numdims.intValue(); i++)
656 td=td.makeArray(state);
659 System.out.println(pn.PPrint(2, true));
664 private NameDescriptor parseName(ParseNode nn) {
665 ParseNode base=nn.getChild("base");
666 ParseNode id=nn.getChild("identifier");
667 //TODO check for bugs with naming things like classes...
668 String terminal = (String) (singleimports.containsKey(id.getTerminal())?singleimports.get(id.getTerminal()):id.getTerminal());
670 return new NameDescriptor(terminal);
672 return new NameDescriptor(parseName(base.getChild("name")),terminal);
675 //only function difference between this and parseName() is that this
676 //does not look for a import mapping.
677 private NameDescriptor parseNameRaw(ParseNode nn) {
678 ParseNode base=nn.getChild("base");
679 ParseNode id=nn.getChild("identifier");
681 return new NameDescriptor(id.getTerminal());
683 return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
686 private void parseFlagDecl(ClassDescriptor cn,ParseNode pn) {
687 String name=pn.getChild("name").getTerminal();
688 FlagDescriptor flag=new FlagDescriptor(name);
689 if (pn.getChild("external")!=null)
694 private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
695 ParseNode mn=pn.getChild("modifier");
696 Modifiers m=parseModifiersList(mn);
697 if(cn.isInterface()) {
698 // TODO add version for normal Java later
699 // Can only be PUBLIC or STATIC or FINAL
700 if((m.isAbstract()) || (m.isAtomic()) || (m.isNative())
701 || (m.isSynchronized())) {
702 throw new Error("Error: field in Interface " + cn.getSymbol() + "can only be PUBLIC or STATIC or FINAL");
704 m.addModifier(Modifiers.PUBLIC);
705 m.addModifier(Modifiers.STATIC);
706 m.addModifier(Modifiers.FINAL);
709 ParseNode tn=pn.getChild("type");
710 TypeDescriptor t=parseTypeDescriptor(tn);
711 assignAnnotationsToType(m,t);
712 ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
713 ParseNodeVector pnv=vn.getChildren();
714 boolean isglobal=pn.getChild("global")!=null;
716 for(int i=0; i<pnv.size(); i++) {
717 ParseNode vardecl=pnv.elementAt(i);
718 ParseNode tmp=vardecl;
719 TypeDescriptor arrayt=t;
720 while (tmp.getChild("single")==null) {
721 arrayt=arrayt.makeArray(state);
722 tmp=tmp.getChild("array");
724 String identifier=tmp.getChild("single").getTerminal();
725 ParseNode epn=vardecl.getChild("initializer");
727 ExpressionNode en=null;
729 en=parseExpression(epn.getFirstChild());
730 en.setNumLine(epn.getFirstChild().getLine());
732 // for static field, the initializer should be considered as a
734 boolean isfirst = false;
735 MethodDescriptor md = (MethodDescriptor)cn.getMethodTable().getFromSameScope("staticblocks");
737 // the first static block for this class
738 Modifiers m_i=new Modifiers();
739 m_i.addModifier(Modifiers.STATIC);
740 md = new MethodDescriptor(m_i, "staticblocks", false);
741 md.setAsStaticBlock();
747 cn.incStaticBlocks();
748 BlockNode bn=new BlockNode();
749 NameNode nn=new NameNode(new NameDescriptor(identifier));
750 nn.setNumLine(en.getNumLine());
751 AssignmentNode an=new AssignmentNode(nn,en,new AssignOperation(1));
752 an.setNumLine(pn.getLine());
753 bn.addBlockStatement(new BlockExpressionNode(an));
755 state.addTreeCode(md,bn);
757 BlockNode obn = state.getMethodBody(md);
758 for(int ii = 0; ii < bn.size(); ii++) {
759 BlockStatementNode bsn = bn.get(ii);
760 obn.addBlockStatement(bsn);
762 state.addTreeCode(md, obn);
769 cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal));
773 private void assignAnnotationsToType(Modifiers modifiers, TypeDescriptor type){
774 Vector<AnnotationDescriptor> annotations=modifiers.getAnnotations();
775 for(int i=0; i<annotations.size(); i++) {
776 // it only supports a marker annotation
777 AnnotationDescriptor an=annotations.elementAt(i);
778 type.addAnnotationMarker(an);
784 private ExpressionNode parseExpression(ParseNode pn) {
785 if (isNode(pn,"assignment"))
786 return parseAssignmentExpression(pn);
787 else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
788 isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
789 isNode(pn,"bitwise_and")||isNode(pn,"equal")||
790 isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
791 isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
792 isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
793 isNode(pn,"rightshift")||isNode(pn,"sub")||
794 isNode(pn,"urightshift")||isNode(pn,"sub")||
795 isNode(pn,"add")||isNode(pn,"mult")||
796 isNode(pn,"div")||isNode(pn,"mod")) {
797 ParseNodeVector pnv=pn.getChildren();
798 ParseNode left=pnv.elementAt(0);
799 ParseNode right=pnv.elementAt(1);
800 Operation op=new Operation(pn.getLabel());
801 OpNode on=new OpNode(parseExpression(left),parseExpression(right),op);
802 on.setNumLine(pn.getLine());
804 } else if (isNode(pn,"unaryplus")||
805 isNode(pn,"unaryminus")||
808 ParseNode left=pn.getFirstChild();
809 Operation op=new Operation(pn.getLabel());
810 OpNode on=new OpNode(parseExpression(left),op);
811 on.setNumLine(pn.getLine());
813 } else if (isNode(pn,"postinc")||
814 isNode(pn,"postdec")) {
815 ParseNode left=pn.getFirstChild();
816 AssignOperation op=new AssignOperation(pn.getLabel());
817 AssignmentNode an=new AssignmentNode(parseExpression(left),null,op);
818 an.setNumLine(pn.getLine());
821 } else if (isNode(pn,"preinc")||
822 isNode(pn,"predec")) {
823 ParseNode left=pn.getFirstChild();
824 AssignOperation op=isNode(pn,"preinc") ? new AssignOperation(AssignOperation.PLUSEQ) : new AssignOperation(AssignOperation.MINUSEQ);
825 AssignmentNode an=new AssignmentNode(parseExpression(left),
826 new LiteralNode("integer",new Integer(1)),op);
827 an.setNumLine(pn.getLine());
829 } else if (isNode(pn,"literal")) {
830 String literaltype=pn.getTerminal();
831 ParseNode literalnode=pn.getChild(literaltype);
832 Object literal_obj=literalnode.getLiteral();
833 LiteralNode ln=new LiteralNode(literaltype, literal_obj);
834 ln.setNumLine(pn.getLine());
836 } else if (isNode(pn, "createobject")) {
837 TypeDescriptor td = parseTypeDescriptor(pn);
839 Vector args = parseArgumentList(pn);
840 boolean isglobal = pn.getChild("global") != null || pn.getChild("scratch") != null;
841 String disjointId = null;
842 if (pn.getChild("disjoint") != null) {
843 disjointId = pn.getChild("disjoint").getTerminal();
845 CreateObjectNode con = new CreateObjectNode(td, isglobal, disjointId);
846 con.setNumLine(pn.getLine());
847 for (int i = 0; i < args.size(); i++) {
848 con.addArgument((ExpressionNode) args.get(i));
850 /* Could have flag set or tag added here */
851 if (pn.getChild("flag_list") != null || pn.getChild("tag_list") != null) {
852 FlagEffects fe = new FlagEffects(null);
853 if (pn.getChild("flag_list") != null)
854 parseFlagEffect(fe, pn.getChild("flag_list"));
856 if (pn.getChild("tag_list") != null)
857 parseTagEffect(fe, pn.getChild("tag_list"));
858 con.addFlagEffects(fe);
862 } else if (isNode(pn,"createobjectcls")) {
863 //TODO::: FIX BUG!!! static fields in caller context need to become parameters
864 TypeDescriptor td=parseTypeDescriptor(pn);
866 ClassDescriptor cnnew=new ClassDescriptor(td.getSymbol()+"$"+innerCount, false);
867 cnnew.setImports(singleimports, multiimports);
868 cnnew.setSuper(td.getSymbol());
869 parseClassBody(cnnew, pn.getChild("decl").getChild("classbody"));
870 Vector args=parseArgumentList(pn);
872 CreateObjectNode con=new CreateObjectNode(td, false, null);
873 con.setNumLine(pn.getLine());
874 for(int i=0; i<args.size(); i++) {
875 con.addArgument((ExpressionNode)args.get(i));
879 } else if (isNode(pn,"createarray")) {
880 //System.out.println(pn.PPrint(3,true));
881 boolean isglobal=pn.getChild("global")!=null||
882 pn.getChild("scratch")!=null;
883 String disjointId=null;
884 if( pn.getChild("disjoint") != null) {
885 disjointId = pn.getChild("disjoint").getTerminal();
887 TypeDescriptor td=parseTypeDescriptor(pn);
888 Vector args=parseDimExprs(pn);
890 if (pn.getChild("dims_opt").getLiteral()!=null)
891 num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
892 for(int i=0; i<(args.size()+num); i++)
893 td=td.makeArray(state);
894 CreateObjectNode con=new CreateObjectNode(td, isglobal, disjointId);
895 con.setNumLine(pn.getLine());
896 for(int i=0; i<args.size(); i++) {
897 con.addArgument((ExpressionNode)args.get(i));
900 } if (isNode(pn,"createarray2")) {
901 TypeDescriptor td=parseTypeDescriptor(pn);
903 if (pn.getChild("dims_opt").getLiteral()!=null)
904 num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
905 for(int i=0; i<num; i++)
906 td=td.makeArray(state);
907 CreateObjectNode con=new CreateObjectNode(td, false, null);
908 con.setNumLine(pn.getLine());
909 ParseNode ipn = pn.getChild("initializer");
910 Vector initializers=parseVariableInitializerList(ipn);
911 ArrayInitializerNode ain = new ArrayInitializerNode(initializers);
912 ain.setNumLine(pn.getLine());
913 con.addArrayInitializer(ain);
915 } else if (isNode(pn,"name")) {
916 NameDescriptor nd=parseName(pn);
917 NameNode nn=new NameNode(nd);
918 nn.setNumLine(pn.getLine());
920 } else if (isNode(pn,"this")) {
921 NameDescriptor nd=new NameDescriptor("this");
922 NameNode nn=new NameNode(nd);
923 nn.setNumLine(pn.getLine());
925 } else if (isNode(pn,"isavailable")) {
926 NameDescriptor nd=new NameDescriptor(pn.getTerminal());
927 NameNode nn=new NameNode(nd);
928 nn.setNumLine(pn.getLine());
929 return new OpNode(nn,null,new Operation(Operation.ISAVAILABLE));
930 } else if (isNode(pn,"methodinvoke1")) {
931 NameDescriptor nd=parseName(pn.getChild("name"));
932 Vector args=parseArgumentList(pn);
933 MethodInvokeNode min=new MethodInvokeNode(nd);
934 min.setNumLine(pn.getLine());
935 for(int i=0; i<args.size(); i++) {
936 min.addArgument((ExpressionNode)args.get(i));
939 } else if (isNode(pn,"methodinvoke2")) {
940 String methodid=pn.getChild("id").getTerminal();
941 ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
942 Vector args=parseArgumentList(pn);
943 MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
944 min.setNumLine(pn.getLine());
945 for(int i=0; i<args.size(); i++) {
946 min.addArgument((ExpressionNode)args.get(i));
949 } else if (isNode(pn,"fieldaccess")) {
950 ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
951 String fieldname=pn.getChild("field").getTerminal();
953 FieldAccessNode fan=new FieldAccessNode(en,fieldname);
954 fan.setNumLine(pn.getLine());
956 } else if (isNode(pn,"arrayaccess")) {
957 ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
958 ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
959 ArrayAccessNode aan=new ArrayAccessNode(en,index);
960 aan.setNumLine(pn.getLine());
962 } else if (isNode(pn,"cast1")) {
964 CastNode cn=new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
965 cn.setNumLine(pn.getLine());
967 } catch (Exception e) {
968 System.out.println(pn.PPrint(1,true));
972 } else if (isNode(pn,"cast2")) {
973 CastNode cn=new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
974 cn.setNumLine(pn.getLine());
976 } else if (isNode(pn, "getoffset")) {
977 TypeDescriptor td=parseTypeDescriptor(pn);
978 String fieldname = pn.getChild("field").getTerminal();
979 //System.out.println("Checking the values of: "+ " td.toString()= " + td.toString()+ " fieldname= " + fieldname);
980 return new OffsetNode(td, fieldname);
981 } else if (isNode(pn, "tert")) {
983 TertiaryNode tn=new TertiaryNode(parseExpression(pn.getChild("cond").getFirstChild()),
984 parseExpression(pn.getChild("trueexpr").getFirstChild()),
985 parseExpression(pn.getChild("falseexpr").getFirstChild()) );
986 tn.setNumLine(pn.getLine());
989 } else if (isNode(pn, "instanceof")) {
990 ExpressionNode exp=parseExpression(pn.getChild("exp").getFirstChild());
991 TypeDescriptor t=parseTypeDescriptor(pn);
992 InstanceOfNode ion=new InstanceOfNode(exp,t);
993 ion.setNumLine(pn.getLine());
995 } else if (isNode(pn, "array_initializer")) {
996 Vector initializers=parseVariableInitializerList(pn);
997 return new ArrayInitializerNode(initializers);
998 } else if (isNode(pn, "class_type")) {
999 TypeDescriptor td=parseTypeDescriptor(pn);
1000 ClassTypeNode ctn=new ClassTypeNode(td);
1001 ctn.setNumLine(pn.getLine());
1003 } else if (isNode(pn, "empty")) {
1006 System.out.println("---------------------");
1007 System.out.println(pn.PPrint(3,true));
1012 private Vector parseDimExprs(ParseNode pn) {
1013 Vector arglist=new Vector();
1014 ParseNode an=pn.getChild("dim_exprs");
1015 if (an==null) /* No argument list */
1017 ParseNodeVector anv=an.getChildren();
1018 for(int i=0; i<anv.size(); i++) {
1019 arglist.add(parseExpression(anv.elementAt(i)));
1024 private Vector parseArgumentList(ParseNode pn) {
1025 Vector arglist=new Vector();
1026 ParseNode an=pn.getChild("argument_list");
1027 if (an==null) /* No argument list */
1029 ParseNodeVector anv=an.getChildren();
1030 for(int i=0; i<anv.size(); i++) {
1031 arglist.add(parseExpression(anv.elementAt(i)));
1036 private Vector[] parseConsArgumentList(ParseNode pn) {
1037 Vector arglist=new Vector();
1038 Vector varlist=new Vector();
1039 ParseNode an=pn.getChild("cons_argument_list");
1040 if (an==null) /* No argument list */
1041 return new Vector[] {varlist, arglist};
1042 ParseNodeVector anv=an.getChildren();
1043 for(int i=0; i<anv.size(); i++) {
1044 ParseNode cpn=anv.elementAt(i);
1045 ParseNode var=cpn.getChild("var");
1046 ParseNode exp=cpn.getChild("exp").getFirstChild();
1047 varlist.add(var.getTerminal());
1048 arglist.add(parseExpression(exp));
1050 return new Vector[] {varlist, arglist};
1053 private Vector parseVariableInitializerList(ParseNode pn) {
1054 Vector varInitList=new Vector();
1055 ParseNode vin=pn.getChild("var_init_list");
1056 if (vin==null) /* No argument list */
1058 ParseNodeVector vinv=vin.getChildren();
1059 for(int i=0; i<vinv.size(); i++) {
1060 varInitList.add(parseExpression(vinv.elementAt(i)));
1065 private ExpressionNode parseAssignmentExpression(ParseNode pn) {
1066 AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
1067 ParseNodeVector pnv=pn.getChild("args").getChildren();
1069 AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
1070 an.setNumLine(pn.getLine());
1075 private void parseMethodDecl(ClassDescriptor cn, ParseNode pn) {
1076 ParseNode headern=pn.getChild("method_header");
1077 ParseNode bodyn=pn.getChild("body");
1078 MethodDescriptor md=parseMethodHeader(headern);
1080 BlockNode bn=parseBlock(bodyn);
1081 bn.setNumLine(pn.getLine()); // assume that method header is located at the beginning of method body
1083 state.addTreeCode(md,bn);
1085 // this is a hack for investigating new language features
1086 // at the AST level, someday should evolve into a nice compiler
1088 //if( cn.getSymbol().equals( ***put a class in here like: "Test" ) &&
1089 // md.getSymbol().equals( ***put your method in here like: "main" )
1091 // bn.setStyle( BlockNode.NORMAL );
1092 // System.out.println( bn.printNode( 0 ) );
1095 } catch (Exception e) {
1096 System.out.println("Error with method:"+md.getSymbol());
1097 e.printStackTrace();
1100 System.out.println("Error with method:"+md.getSymbol());
1101 e.printStackTrace();
1106 private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
1107 ParseNode mn=pn.getChild("modifiers");
1108 Modifiers m=parseModifiersList(mn);
1109 ParseNode cdecl=pn.getChild("constructor_declarator");
1110 boolean isglobal=cdecl.getChild("global")!=null;
1111 String name=cdecl.getChild("name").getChild("identifier").getTerminal();
1112 MethodDescriptor md=new MethodDescriptor(m, name, isglobal);
1113 ParseNode paramnode=cdecl.getChild("parameters");
1114 parseParameterList(md,paramnode);
1115 ParseNode bodyn0=pn.getChild("body");
1116 ParseNode bodyn=bodyn0.getChild("constructor_body");
1119 if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
1120 bn=parseBlock(bodyn);
1123 if (bodyn!=null&&bodyn.getChild("superinvoke")!=null) {
1124 ParseNode sin=bodyn.getChild("superinvoke");
1125 NameDescriptor nd=new NameDescriptor("super");
1126 Vector args=parseArgumentList(sin);
1127 MethodInvokeNode min=new MethodInvokeNode(nd);
1128 min.setNumLine(sin.getLine());
1129 for(int i=0; i<args.size(); i++) {
1130 min.addArgument((ExpressionNode)args.get(i));
1132 BlockExpressionNode ben=new BlockExpressionNode(min);
1133 bn.addFirstBlockStatement(ben);
1135 } else if (bodyn!=null&&bodyn.getChild("explconstrinv")!=null) {
1136 ParseNode eci=bodyn.getChild("explconstrinv");
1137 NameDescriptor nd=new NameDescriptor(cn.getSymbol());
1138 Vector args=parseArgumentList(eci);
1139 MethodInvokeNode min=new MethodInvokeNode(nd);
1140 min.setNumLine(eci.getLine());
1141 for(int i=0; i<args.size(); i++) {
1142 min.addArgument((ExpressionNode)args.get(i));
1144 BlockExpressionNode ben=new BlockExpressionNode(min);
1145 ben.setNumLine(eci.getLine());
1146 bn.addFirstBlockStatement(ben);
1148 state.addTreeCode(md,bn);
1151 private void parseStaticBlockDecl(ClassDescriptor cn, ParseNode pn) {
1152 // Each class maintains one MethodDecscriptor which combines all its
1153 // static blocks in their declaration order
1154 boolean isfirst = false;
1155 MethodDescriptor md = (MethodDescriptor)cn.getMethodTable().getFromSameScope("staticblocks");
1157 // the first static block for this class
1158 Modifiers m_i=new Modifiers();
1159 m_i.addModifier(Modifiers.STATIC);
1160 md = new MethodDescriptor(m_i, "staticblocks", false);
1161 md.setAsStaticBlock();
1164 ParseNode bodyn=pn.getChild("body");
1168 cn.incStaticBlocks();
1170 if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
1171 bn=parseBlock(bodyn);
1175 state.addTreeCode(md,bn);
1177 BlockNode obn = state.getMethodBody(md);
1178 for(int i = 0; i < bn.size(); i++) {
1179 BlockStatementNode bsn = bn.get(i);
1180 obn.addBlockStatement(bsn);
1182 state.addTreeCode(md, obn);
1187 public BlockNode parseBlock(ParseNode pn) {
1188 this.m_taskexitnum = 0;
1189 if (pn==null||isEmpty(pn.getTerminal()))
1190 return new BlockNode();
1191 ParseNode bsn=pn.getChild("block_statement_list");
1192 return parseBlockHelper(bsn);
1195 private BlockNode parseBlockHelper(ParseNode pn) {
1196 ParseNodeVector pnv=pn.getChildren();
1197 BlockNode bn=new BlockNode();
1198 for(int i=0; i<pnv.size(); i++) {
1199 Vector bsv=parseBlockStatement(pnv.elementAt(i));
1200 for(int j=0; j<bsv.size(); j++) {
1201 bn.addBlockStatement((BlockStatementNode)bsv.get(j));
1207 public BlockNode parseSingleBlock(ParseNode pn) {
1208 BlockNode bn=new BlockNode();
1209 Vector bsv=parseBlockStatement(pn);
1210 for(int j=0; j<bsv.size(); j++) {
1211 bn.addBlockStatement((BlockStatementNode)bsv.get(j));
1213 bn.setStyle(BlockNode.NOBRACES);
1217 public Vector parseSESEBlock(Vector parentbs, ParseNode pn) {
1218 ParseNodeVector pnv=pn.getChildren();
1219 Vector bv=new Vector();
1220 for(int i=0; i<pnv.size(); i++) {
1221 bv.addAll(parseBlockStatement(pnv.elementAt(i)));
1226 public Vector parseBlockStatement(ParseNode pn) {
1227 Vector blockstatements=new Vector();
1228 if (isNode(pn,"tag_declaration")) {
1229 String name=pn.getChild("single").getTerminal();
1230 String type=pn.getChild("type").getTerminal();
1232 TagDeclarationNode tdn=new TagDeclarationNode(name, type);
1233 tdn.setNumLine(pn.getLine());
1235 blockstatements.add(tdn);
1236 } else if (isNode(pn,"local_variable_declaration")) {
1238 ParseNode mn=pn.getChild("modifiers");
1239 TypeDescriptor t=parseTypeDescriptor(pn);
1241 Modifiers m=parseModifiersList(mn);
1242 assignAnnotationsToType(m, t);
1244 ParseNode vn=pn.getChild("variable_declarators_list");
1245 ParseNodeVector pnv=vn.getChildren();
1246 for(int i=0; i<pnv.size(); i++) {
1247 ParseNode vardecl=pnv.elementAt(i);
1250 ParseNode tmp=vardecl;
1251 TypeDescriptor arrayt=t;
1253 while (tmp.getChild("single")==null) {
1254 arrayt=arrayt.makeArray(state);
1255 tmp=tmp.getChild("array");
1257 String identifier=tmp.getChild("single").getTerminal();
1259 ParseNode epn=vardecl.getChild("initializer");
1262 ExpressionNode en=null;
1264 en=parseExpression(epn.getFirstChild());
1266 DeclarationNode dn=new DeclarationNode(new VarDescriptor(arrayt, identifier),en);
1267 dn.setNumLine(tmp.getLine());
1269 blockstatements.add(dn);
1271 } else if (isNode(pn,"nop")) {
1273 } else if (isNode(pn,"expression")) {
1274 BlockExpressionNode ben=new BlockExpressionNode(parseExpression(pn.getFirstChild()));
1275 ben.setNumLine(pn.getLine());
1276 blockstatements.add(ben);
1277 } else if (isNode(pn,"ifstatement")) {
1278 IfStatementNode isn=new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
1279 parseSingleBlock(pn.getChild("statement").getFirstChild()),
1280 pn.getChild("else_statement")!=null ? parseSingleBlock(pn.getChild("else_statement").getFirstChild()) : null);
1281 isn.setNumLine(pn.getLine());
1283 blockstatements.add(isn);
1284 } else if (isNode(pn,"switch_statement")) {
1285 // TODO add version for normal Java later
1286 SwitchStatementNode ssn=new SwitchStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
1287 parseSingleBlock(pn.getChild("statement").getFirstChild()));
1288 ssn.setNumLine(pn.getLine());
1289 blockstatements.add(ssn);
1290 } else if (isNode(pn,"switch_block_list")) {
1291 // TODO add version for normal Java later
1292 ParseNodeVector pnv=pn.getChildren();
1293 for(int i=0; i<pnv.size(); i++) {
1294 ParseNode sblockdecl=pnv.elementAt(i);
1296 if(isNode(sblockdecl, "switch_block")) {
1297 ParseNode lpn=sblockdecl.getChild("switch_labels").getChild("switch_label_list");
1298 ParseNodeVector labelv=lpn.getChildren();
1299 Vector<SwitchLabelNode> slv = new Vector<SwitchLabelNode>();
1300 for(int j=0; j<labelv.size(); j++) {
1301 ParseNode labeldecl=labelv.elementAt(j);
1302 if(isNode(labeldecl, "switch_label")) {
1303 SwitchLabelNode sln=new SwitchLabelNode(parseExpression(labeldecl.getChild("constant_expression").getFirstChild()), false);
1304 sln.setNumLine(labeldecl.getLine());
1305 slv.addElement(sln);
1306 } else if(isNode(labeldecl, "default_switch_label")) {
1307 SwitchLabelNode sln=new SwitchLabelNode(null, true);
1308 sln.setNumLine(labeldecl.getLine());
1309 slv.addElement(sln);
1313 SwitchBlockNode sbn=new SwitchBlockNode(slv,
1314 parseSingleBlock(sblockdecl.getChild("switch_statements").getFirstChild()));
1315 sbn.setNumLine(sblockdecl.getLine());
1317 blockstatements.add(sbn);
1321 } else if (isNode(pn, "trycatchstatement")) {
1322 // TODO add version for normal Java later
1323 // Do not fully support exceptions now. Only make sure that if there are no
1324 // exceptions thrown, the execution is right
1325 ParseNode tpn = pn.getChild("tryblock").getFirstChild();
1326 BlockNode bn=parseBlockHelper(tpn);
1327 blockstatements.add(new SubBlockNode(bn));
1329 ParseNode fbk = pn.getChild("finallyblock");
1331 ParseNode fpn = fbk.getFirstChild();
1332 BlockNode fbn=parseBlockHelper(fpn);
1333 blockstatements.add(new SubBlockNode(fbn));
1335 } else if (isNode(pn, "throwstatement")) {
1336 // TODO Simply return here
1337 //blockstatements.add(new ReturnNode());
1338 } else if (isNode(pn,"taskexit")) {
1340 if (pn.getChild("flag_effects_list")!=null)
1341 vfe=parseFlags(pn.getChild("flag_effects_list"));
1343 if (pn.getChild("cons_checks")!=null)
1344 ccs=parseChecks(pn.getChild("cons_checks"));
1345 TaskExitNode ten=new TaskExitNode(vfe, ccs, this.m_taskexitnum++);
1346 ten.setNumLine(pn.getLine());
1347 blockstatements.add(ten);
1348 } else if (isNode(pn,"atomic")) {
1349 BlockNode bn=parseBlockHelper(pn);
1350 AtomicNode an=new AtomicNode(bn);
1351 an.setNumLine(pn.getLine());
1352 blockstatements.add(an);
1353 } else if (isNode(pn,"synchronized")) {
1354 BlockNode bn=parseBlockHelper(pn.getChild("block"));
1355 ExpressionNode en=parseExpression(pn.getChild("expr").getFirstChild());
1356 SynchronizedNode sn=new SynchronizedNode(en, bn);
1357 sn.setNumLine(pn.getLine());
1358 blockstatements.add(sn);
1359 } else if (isNode(pn,"return")) {
1360 if (isEmpty(pn.getTerminal()))
1361 blockstatements.add(new ReturnNode());
1363 ExpressionNode en=parseExpression(pn.getFirstChild());
1364 ReturnNode rn=new ReturnNode(en);
1365 rn.setNumLine(pn.getLine());
1366 blockstatements.add(rn);
1368 } else if (isNode(pn,"block_statement_list")) {
1369 BlockNode bn=parseBlockHelper(pn);
1370 blockstatements.add(new SubBlockNode(bn));
1371 } else if (isNode(pn,"empty")) {
1373 } else if (isNode(pn,"statement_expression_list")) {
1374 ParseNodeVector pnv=pn.getChildren();
1375 BlockNode bn=new BlockNode();
1376 for(int i=0; i<pnv.size(); i++) {
1377 ExpressionNode en=parseExpression(pnv.elementAt(i));
1378 blockstatements.add(new BlockExpressionNode(en));
1380 bn.setStyle(BlockNode.EXPRLIST);
1381 } else if (isNode(pn,"forstatement")) {
1382 BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
1383 BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
1384 ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1385 BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1386 if(condition == null) {
1387 // no condition clause, make a 'true' expression as the condition
1388 condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1390 LoopNode ln=new LoopNode(init,condition,update,body);
1391 ln.setNumLine(pn.getLine());
1392 blockstatements.add(ln);
1393 } else if (isNode(pn,"whilestatement")) {
1394 ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1395 BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1396 if(condition == null) {
1397 // no condition clause, make a 'true' expression as the condition
1398 condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1400 blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
1401 } else if (isNode(pn,"dowhilestatement")) {
1402 ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
1403 BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
1404 if(condition == null) {
1405 // no condition clause, make a 'true' expression as the condition
1406 condition = (ExpressionNode)new LiteralNode("boolean", new Boolean(true));
1408 blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
1409 } else if (isNode(pn,"sese")) {
1410 ParseNode pnID=pn.getChild("identifier");
1412 if( pnID != null ) { stID=pnID.getFirstChild().getTerminal(); }
1413 SESENode start=new SESENode(stID);
1414 start.setNumLine(pn.getLine());
1415 SESENode end =new SESENode(stID);
1416 start.setEnd( end );
1417 end.setStart( start );
1418 blockstatements.add(start);
1419 blockstatements.addAll(parseSESEBlock(blockstatements,pn.getChild("body").getFirstChild()));
1420 blockstatements.add(end);
1421 } else if (isNode(pn,"continue")) {
1422 ContinueBreakNode cbn=new ContinueBreakNode(false);
1423 cbn.setNumLine(pn.getLine());
1424 blockstatements.add(cbn);
1425 } else if (isNode(pn,"break")) {
1426 ContinueBreakNode cbn=new ContinueBreakNode(true);
1427 cbn.setNumLine(pn.getLine());
1428 blockstatements.add(cbn);
1430 } else if (isNode(pn,"genreach")) {
1431 String graphName = pn.getChild("graphName").getTerminal();
1432 blockstatements.add( new GenReachNode( graphName ) );
1434 } else if(isNode(pn,"labeledstatement")){
1435 String label = pn.getChild("name").getTerminal();
1436 BlockNode bn=parseSingleBlock(pn.getChild("statement").getFirstChild());
1438 blockstatements.add(new SubBlockNode(bn));
1440 System.out.println("---------------");
1441 System.out.println(pn.PPrint(3,true));
1444 return blockstatements;
1447 public MethodDescriptor parseMethodHeader(ParseNode pn) {
1448 ParseNode mn=pn.getChild("modifiers");
1449 Modifiers m=parseModifiersList(mn);
1451 ParseNode tn=pn.getChild("returntype");
1452 TypeDescriptor returntype;
1454 returntype=parseTypeDescriptor(tn);
1456 returntype=new TypeDescriptor(TypeDescriptor.VOID);
1458 ParseNode pmd=pn.getChild("method_declarator");
1459 String name=pmd.getChild("name").getTerminal();
1460 MethodDescriptor md=new MethodDescriptor(m, returntype, name);
1462 ParseNode paramnode=pmd.getChild("parameters");
1463 parseParameterList(md,paramnode);
1467 public void parseParameterList(MethodDescriptor md, ParseNode pn) {
1468 ParseNode paramlist=pn.getChild("formal_parameter_list");
1469 if (paramlist==null)
1471 ParseNodeVector pnv=paramlist.getChildren();
1472 for(int i=0; i<pnv.size(); i++) {
1473 ParseNode paramn=pnv.elementAt(i);
1475 if (isNode(paramn, "tag_parameter")) {
1476 String paramname=paramn.getChild("single").getTerminal();
1477 TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
1478 md.addTagParameter(type, paramname);
1481 TypeDescriptor type=parseTypeDescriptor(paramn);
1483 ParseNode tmp=paramn;
1484 while (tmp.getChild("single")==null) {
1485 type=type.makeArray(state);
1486 tmp=tmp.getChild("array");
1488 String paramname=tmp.getChild("single").getTerminal();
1490 md.addParameter(type, paramname);
1491 if(isNode(paramn, "annotation_parameter")){
1492 ParseNode bodynode=paramn.getChild("annotation_body");
1493 parseParameterAnnotation(bodynode,type);
1500 public Modifiers parseModifiersList(ParseNode pn) {
1501 Modifiers m=new Modifiers();
1502 ParseNode modlist=pn.getChild("modifier_list");
1503 if (modlist!=null) {
1504 ParseNodeVector pnv=modlist.getChildren();
1505 for(int i=0; i<pnv.size(); i++) {
1506 ParseNode modn=pnv.elementAt(i);
1507 if (isNode(modn,"public"))
1508 m.addModifier(Modifiers.PUBLIC);
1509 else if (isNode(modn,"protected"))
1510 m.addModifier(Modifiers.PROTECTED);
1511 else if (isNode(modn,"private"))
1512 m.addModifier(Modifiers.PRIVATE);
1513 else if (isNode(modn,"static"))
1514 m.addModifier(Modifiers.STATIC);
1515 else if (isNode(modn,"final"))
1516 m.addModifier(Modifiers.FINAL);
1517 else if (isNode(modn,"native"))
1518 m.addModifier(Modifiers.NATIVE);
1519 else if (isNode(modn,"synchronized"))
1520 m.addModifier(Modifiers.SYNCHRONIZED);
1521 else if (isNode(modn,"atomic"))
1522 m.addModifier(Modifiers.ATOMIC);
1523 else if (isNode(modn,"abstract"))
1524 m.addModifier(Modifiers.ABSTRACT);
1525 else if (isNode(modn,"volatile"))
1526 m.addModifier(Modifiers.VOLATILE);
1527 else if (isNode(modn,"transient"))
1528 m.addModifier(Modifiers.TRANSIENT);
1529 else if(isNode(modn,"annotation_list"))
1530 parseAnnotationList(modn,m);
1532 throw new Error("Unrecognized Modifier:"+modn.getLabel());}
1538 private void parseAnnotationList(ParseNode pn, Modifiers m) {
1539 ParseNodeVector pnv = pn.getChildren();
1540 for (int i = 0; i < pnv.size(); i++) {
1541 ParseNode body_list = pnv.elementAt(i);
1542 if (isNode(body_list, "annotation_body")) {
1543 ParseNode body_node = body_list.getFirstChild();
1544 if (isNode(body_node, "marker_annotation")) {
1545 m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal()));
1546 } else if (isNode(body_node, "single_annotation")) {
1547 m.addAnnotation(new AnnotationDescriptor(body_node.getChild("name").getTerminal(),
1548 body_node.getChild("element_value").getTerminal()));
1549 } else if (isNode(body_node, "normal_annotation")) {
1550 throw new Error("Annotation with multiple data members is not supported yet.");
1556 private void parseParameterAnnotation(ParseNode body_list,TypeDescriptor type){
1557 ParseNode body_node = body_list.getFirstChild();
1558 if (isNode(body_node, "marker_annotation")) {
1559 type.addAnnotationMarker(new AnnotationDescriptor(body_node.getChild("name").getTerminal()));
1560 } else if (isNode(body_node, "single_annotation")) {
1561 type.addAnnotationMarker(new AnnotationDescriptor(body_node.getChild("name").getTerminal(),
1562 body_node.getChild("element_value").getTerminal()));
1563 } else if (isNode(body_node, "normal_annotation")) {
1564 throw new Error("Annotation with multiple data members is not supported yet.");
1568 private boolean isNode(ParseNode pn, String label) {
1569 if (pn.getLabel().equals(label))
1574 private static boolean isEmpty(ParseNode pn) {
1575 if (pn.getLabel().equals("empty"))
1581 private static boolean isEmpty(String s) {
1582 if (s.equals("empty"))
1588 /** Throw an exception if something is unexpected */
1589 private void check(ParseNode pn, String label) {
1591 throw new Error(pn+ "IE: Expected '" + label + "', got null");
1593 if (!pn.getLabel().equals(label)) {
1594 throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");