IMPORTS: [| import org.eclipse.jdt.core.dom.*; import java.util.*; import edu.berkeley.cs164.interp.*; |] PROLOGUE: [| public static AST ast = new AST(new HashMap()); public static int numClasses = 0; public static List types = new ArrayList(); public void createCompilationUnit(){ CompilationUnit cu = ast.newCompilationUnit(); List cutypes = cu.types(); //add the type declarations for (int i = 0; i < numClasses; i++){ cutypes.add(types.get(i)); } numClasses = 0; push(cu); //the lines below are for printing out the AST using the ASTPrinter from PA1. //If you want to use it, you need to copy the file ASTPrinter.java from PA1. /* ASTPrinter debug = new ASTPrinter(); System.out.println("*** AST ***"); cu.accept(debug); */ } //for the case "class A" public void createTypeDeclarationNoExtend(){ TypeDeclaration td = ast.newTypeDeclaration(); td.setName(makeSimpleName(-1)); numClasses++; types.add(td); push(td.bodyDeclarations()); } //for the case "class A extends B" public void createTypeDeclarationExtend(){ TypeDeclaration td = ast.newTypeDeclaration(); td.setName(makeSimpleName(-3)); td.setSuperclass(makeSimpleName(-1)); numClasses++; types.add(td); push(td.bodyDeclarations()); } //makes an infix expression node and push it on the semantic stack //expects the right operand to be on the top of stack, and the left operand //to be the third element on the stack upon entry private void makeInfix(InfixExpression.Operator op) { InfixExpression e = ast.newInfixExpression(); e.setLeftOperand((Expression)peek(-2)); e.setRightOperand((Expression)peek(0)); e.setOperator(op); push(e); } //makes an prefix expression node and push it on the semantic stack //expects the operand to be on the top of stack upon entry private void makePrefix(PrefixExpression.Operator op) { PrefixExpression p = ast.newPrefixExpression(); p.setOperand((Expression)peek(0)); p.setOperator(op); push(p); } //offset is the token's position on the semantic stack private SimpleName makeSimpleName(int offset) { return ast.newSimpleName(((Token)peek(offset)).getLexeme()); } //o must be a token private SimpleName makeSimpleName(Object o){ return ast.newSimpleName(((Token) o).getLexeme()); } private String fixStringLit(String lexeme) { char[] lexemeChars = lexeme.toCharArray(); StringBuffer ret = new StringBuffer(); // skip the first and last quote characters for (int i = 1; i < lexemeChars.length - 1; i++) { if (lexemeChars[i] == '\\') { i++; switch (lexemeChars[i]) { case 'n': ret.append('\n'); break; case '\"': ret.append('\"'); break; case '\'': ret.append('\''); break; case '\\': ret.append('\\'); break; case ' ': ret.append(' '); break; default: assert false; } } else { ret.append(lexemeChars[i]); } } return ret.toString(); } |] PROGRAM -> CLASSDECLLIST [| createCompilationUnit(); |]; CLASSDECLLIST -> CLASSDECL CLASSDECLLISTY; CLASSDECLLISTY -> _ | CLASSDECLLIST ; CLASSDECL -> CLASSDECLY; CLASSDECLY -> [| createTypeDeclarationNoExtend(); |] DECLS | [| createTypeDeclarationExtend(); |] DECLS ; DECLS -> _ | DECL [| List declarations = (List) peek(-1); declarations.add(peek(0)); push(peek(-1)); |] DECLS; DECL -> OPTSTATIC VOIDORNOT [| push(peek(0)); |]; VOIDORNOT -> TYPE METHODORFIELD [| push(peek(0)); |] | METHODDECLVOID [| push(peek(0)); |] ; METHODORFIELD -> METHODNONVOID [| push(peek(0)); |] | FIELDDECL [| push(peek(0)); |]; OPTSTATIC -> [| push(peek(0)); |] | _ [| push(null); |] ; FIELDDECL -> [| VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment(); vdf.setName((SimpleName)ast.newSimpleName(((Token)peek(-1)).getLexeme())); FieldDeclaration fd = ast.newFieldDeclaration(vdf); fd.setType((Type)peek(-2)); if (peek(-3) != null) { // static fd.setModifiers(Modifier.STATIC); } push(fd); |] FIELDDECLY [| push(peek(0)); |] | [| VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment(); vdf.setName((SimpleName)ast.newSimpleName(((Token)peek(-1)).getLexeme())); FieldDeclaration fd = ast.newFieldDeclaration(vdf); fd.setType((Type)peek(-2)); if (peek(-3) != null) { // static fd.setModifiers(Modifier.STATIC); } push(fd); |]; FIELDDECLY -> [| VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment(); vdf.setName(ast.newSimpleName(((Token)peek(-1)).getLexeme())); ((FieldDeclaration)peek(-2)).fragments().add(vdf); push(peek(-2)); |] | [| VariableDeclarationFragment vdf = ast.newVariableDeclarationFragment(); vdf.setName(ast.newSimpleName(((Token)peek(-1)).getLexeme())); ((FieldDeclaration)peek(-2)).fragments().add(vdf); push(peek(-2)); |] FIELDDECLY [| push(peek(0)); |]; TYPE -> [| push(ast.newPrimitiveType(PrimitiveType.INT)); |] | [| push(ast.newPrimitiveType(PrimitiveType.BOOLEAN)); |] | [| push(ast.newSimpleType(ast.newSimpleName( ((Token)peek(0)).getLexeme()))); |] ; PRIMITIVETYPE -> [| push(ast.newPrimitiveType(PrimitiveType.INT)); |] | [| push(ast.newPrimitiveType(PrimitiveType.BOOLEAN)); |] ; METHODDECLVOID -> [| push(ast.newPrimitiveType(PrimitiveType.VOID)); |] [| push(new ArrayList()); |] PARAMS BLOCK [| MethodDeclaration m = ast.newMethodDeclaration(); m.setBody((Block)peek(0)); m.setName(makeSimpleName(-5)); m.setReturnType((Type)peek(-6)); List paramsList = (List)peek(-2); for (Iterator iter = paramsList.iterator(); iter.hasNext(); ) { m.parameters().add(iter.next()); } if (peek(-8) != null) { // static m.setModifiers(Modifier.STATIC); } push(m); |] ; METHODNONVOID -> [| push(new ArrayList()); |] PARAMS BLOCK [| MethodDeclaration m = ast.newMethodDeclaration(); m.setBody((Block)peek(0)); m.setName(makeSimpleName(-5)); m.setReturnType((Type)peek(-6)); List paramsList = (List)peek(-2); for (Iterator iter = paramsList.iterator(); iter.hasNext(); ) { m.parameters().add(iter.next()); } if (peek(-7) != null) { // static m.setModifiers(Modifier.STATIC); } push(m); |] ; BLOCK -> [| push(new ArrayList()); |] STMTLIST [| Block b = ast.newBlock(); List stmts = (List)peek(-1); for (Iterator iter = stmts.iterator(); iter.hasNext(); ) { b.statements().add(iter.next()); } push(b); |]; PARAMS -> NONEMPTYPARAMS | _ ; NONEMPTYPARAMS -> TYPE [| SingleVariableDeclaration s = ast.newSingleVariableDeclaration(); s.setName(makeSimpleName(0)); s.setType((Type)peek(-1)); ((List)peek(-2)).add(s); push(peek(-2)); |] NEPARAMSTAIL ; NEPARAMSTAIL -> [| push(peek(-1)); |] NONEMPTYPARAMS | _ ; //Your fun starts here for step 5 STMTLIST -> STMT -> EXPR ->