// VoidMethodDeclaration ::= void id '(' ParameterList? ')' { Statement* } private MethodDecl parseVoidMethodDeclaration( boolean isPrivate, boolean isStatic, SourcePosition pos) { SourcePosition currentPos = token.posn; accept(TokenKind.VOID); String methodName = accept(TokenKind.ID); accept(TokenKind.LEFTPAREN); // Initialize empty list in case there are no parameters ParameterDeclList parameterDeclList = new ParameterDeclList(); if (token.kind != TokenKind.RIGHTPAREN) parameterDeclList = parseParameterList(); accept(TokenKind.RIGHTPAREN); accept(TokenKind.LEFTBRACKET); // Initialize empty list in case there are no statements StatementList statementList = new StatementList(); while (token.kind != TokenKind.RIGHTBRACKET) statementList.add(parseStatement(new BaseType(TypeKind.VOID, pos))); accept(TokenKind.RIGHTBRACKET); return new MethodDecl( new FieldDecl( isPrivate, isStatic, new BaseType(TypeKind.VOID, currentPos), methodName, pos), parameterDeclList, statementList, pos); }
/* * Type id ( ; | '(' ParameterList? ')' '{' Statement* '}' ) */ private Object parseFieldOrNonVoidMethodDeclaration( boolean isPrivate, boolean isStatic, SourcePosition pos) { Type type = parseType(); String name = accept(TokenKind.ID); switch (token.kind) { // Field declaration case SEMICOLON: accept(TokenKind.SEMICOLON); return new FieldDecl(isPrivate, isStatic, type, name, pos); // '(' ParameterList? ')' '{' Statement* '}' // Method declaration case LEFTPAREN: { accept(TokenKind.LEFTPAREN); // Initialize empty list in case there are no parameters ParameterDeclList parameterDeclList = new ParameterDeclList(); if (token.kind != TokenKind.RIGHTPAREN) { parameterDeclList = parseParameterList(); } accept(TokenKind.RIGHTPAREN); accept(TokenKind.LEFTBRACKET); // Initialize empty list in case there are no statements StatementList statementList = new StatementList(); while (token.kind != TokenKind.RIGHTBRACKET) statementList.add(parseStatement(type)); accept(TokenKind.RIGHTBRACKET); return new MethodDecl( new FieldDecl(isPrivate, isStatic, type, name, pos), parameterDeclList, statementList, pos); } default: parseError("Invalid Term - expecting SEMICOLON or LEFTPAREN but found " + token.kind); return null; } }
private Statement parseStatement(Type returnType) { SourcePosition currentPos = token.posn; switch (token.kind) { // { Statement* } case LEFTBRACKET: accept(TokenKind.LEFTBRACKET); StatementList statementList = new StatementList(); while (token.kind != TokenKind.RIGHTBRACKET) { statementList.add(parseStatement(returnType)); } accept(TokenKind.RIGHTBRACKET); return new BlockStmt(statementList, currentPos); case ID: ClassType classType = new ClassType(new Identifier(token), currentPos); IdRef idRef = new IdRef(new Identifier(token), currentPos); acceptIt(); if (token.kind == TokenKind.LEFTSQUAREBRACKET) { acceptIt(); // id[] id = Expression ; if (token.kind == TokenKind.RIGHTSQUAREBRACKET) { acceptIt(); return parseIDArrayDeclarationStatement(classType); } else { // id [ Expression ] = Expression ; return parseIDIndexedAssignStatement(idRef); } } // id id = Expression ; else if (token.kind == TokenKind.ID) { String variableName = acceptIt(); return parseIDDeclarationStatement(classType, variableName); } // id ( . id)* ( = Expression | '('ArgumentList?')' ) ; else if (token.kind == TokenKind.DOT || token.kind == TokenKind.ASSIGNMENTEQUAL || token.kind == TokenKind.LEFTPAREN) { return parseQualifiedStatements(idRef); } else { parseError( "Invalid Term - expecting LEFTSQUAREBRACKET, ID, DOT, or ASSIGNMENTEQUAL but found " + token.kind); // Never reached return null; } case INT: return parseIntOrIntArrayDeclarationStatement(); case BOOLEAN: return parseBooleanDeclarationStatement(); case THIS: // this ( . id )* ( = Expression | '('ArgumentList?')' ) ; acceptIt(); Reference thisRef = new ThisRef(currentPos); return parseQualifiedStatements(thisRef); case RETURN: return parseReturnStatement(returnType); case IF: return parseIfStatement(returnType); case WHILE: return parseWhileStatement(returnType); default: parseError( "Invalid Term - expecting LEFTBRACKET, ID, INT, BOOLEAN, THIS, RETURN, IF, or WHILE but found " + token.kind); return null; } }