package Compiler; import java.util.ArrayList; import java.util.List; public class Parser { private final List tokens; private int currentToken = 0; Parser(List tokens){ this.tokens=tokens; } List parse(){ List statements = new ArrayList<>(); try{ while (!checkEOF()){ statements.add(declaration()); } }catch (Error e){ return null; } return statements; } //Clean up and reduce code mess private Statement declaration(){ if (matchAndAdvance(TokenType.INT)){ if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ Token varName = getPreviousToken(); return new Statement.VariableDeclaration(varName,"int"); } } } else if (matchAndAdvance(TokenType.REAL)){ if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ Token varName = getPreviousToken(); return new Statement.VariableDeclaration(varName,"real"); } } } return statement(); } private Statement statement(){ if (matchAndAdvance(TokenType.PRINT)){ Expression expression = expression(); return new Statement.PrintStatement(expression); }else if (matchAndAdvance(TokenType.IF)){ Statement statement = ifStatement(); return statement; } return expressionStatement(); } //Could be cleaned up to handle else statements better private Statement ifStatement(){ Expression condition = expression(); if(matchOrError(TokenType.THEN, "then expected after if statement")){ List statements = new ArrayList<>(); List elseStatements = new ArrayList<>(); while(!matchAndAdvance(TokenType.ENDIF)&&!checkToken(TokenType.ELSE)){ if(checkEOF()){ throw error("endif missing"); } statements.add(declaration()); } if(matchAndAdvance(TokenType.ELSE)){ while(!matchAndAdvance(TokenType.ENDIF)){ if(checkEOF()){ throw error("endif missing"); } elseStatements.add(declaration()); } } Statement ifstatement = new Statement.IfStatement(condition, statements,elseStatements); return ifstatement; } return null; } private Statement expressionStatement(){ Expression expression = assignment(); return new Statement.ExpressionStatement(expression); } private Expression assignment(){ Expression variable = expression(); if (matchAndAdvance(TokenType.EQUALS)){ Expression assignedvalue = expression(); if (variable instanceof Expression.Variable){ return new Expression.AssignmentExpression(((Expression.Variable)variable).name,assignedvalue); } throw error("Incorrect assignment operation"); } return variable; } private Expression expression(){ Expression createdExpression = equality(); return createdExpression; } private Expression equality(){ Expression createdExpression = comparison(); while (matchAndAdvance(TokenType.EQUALITY)){ Token op = getPreviousToken(); Expression right = comparison(); createdExpression = new Expression.Binary(createdExpression, op, right); } return createdExpression; } private Expression comparison(){ Expression createdExpression = term(); while (matchAndAdvance(TokenType.GREATER)||matchAndAdvance(TokenType.LESS)){ Token op = getPreviousToken(); Expression right = term(); createdExpression = new Expression.Binary(createdExpression, op, right); } return createdExpression; } private Expression term(){ Expression createdExpression = factor(); while (matchAndAdvance(TokenType.PLUS)||matchAndAdvance(TokenType.MINUS)){ Token op = getPreviousToken(); Expression right = factor(); createdExpression = new Expression.Binary(createdExpression, op, right); } return createdExpression; } private Expression factor(){ Expression createdExpression = primary(); while (matchAndAdvance(TokenType.STAR)||matchAndAdvance(TokenType.SLASH)){ Token op = getPreviousToken(); Expression right = primary(); createdExpression = new Expression.Binary(createdExpression, op, right); } return createdExpression; } private Expression primary(){ if (matchAndAdvance(TokenType.NUMBER)){ if(getPreviousToken().value instanceof Integer){ return new Expression.Literal(getPreviousToken(),"int"); } else if(getPreviousToken().value instanceof Double){ return new Expression.Literal(getPreviousToken(),"double"); } } if (matchAndAdvance(TokenType.IDENTIFIER)) { return new Expression.Variable(getPreviousToken()); } if (matchAndAdvance(TokenType.LEFT_PAREN)){ Expression expr = expression(); if (matchAndAdvance(TokenType.RIGHT_PAREN)){ return new Expression.BracketedExpression(expr); } else{ throw error("Expected ')"); } } throw error("Expected Expression"); } private void advanceToken(){ if (!checkEOF()) { currentToken++; }; } private boolean matchAndAdvance(TokenType type){ if (checkToken(type)) { advanceToken(); return true; } return false; } private boolean matchOrError(TokenType type,String errorMessage){ if (matchAndAdvance(type)){ return true; } throw error(errorMessage); } private boolean checkToken(TokenType type){ if (checkEOF()) return false; return getCurrentToken().type == type; } private boolean checkEOF(){ return tokens.get(currentToken).type==TokenType.EOF; } private Token getCurrentToken(){ return tokens.get(currentToken); } private Token getPreviousToken(){ return tokens.get(currentToken - 1); } private Error error(String message){ Language.displayError(message); return new Error(); } }