diff options
author | Alfie Eagleton <67986414+TheAlfanator@users.noreply.github.com> | 2021-11-03 16:56:38 +0000 |
---|---|---|
committer | Alfie Eagleton <67986414+TheAlfanator@users.noreply.github.com> | 2021-11-03 16:56:38 +0000 |
commit | 85345d7d80eeb950ab64633ae1cb1f1c5dc87269 (patch) | |
tree | b353c985d4cdf51517a907efd9c6968a62db5655 /code/Interpreter2/src/Interpreter/Parser.java | |
parent | 85e2726ddedd2981425c5ac07f7257bce1a6ddbf (diff) | |
download | esotericFORTRAN-85345d7d80eeb950ab64633ae1cb1f1c5dc87269.tar.gz esotericFORTRAN-85345d7d80eeb950ab64633ae1cb1f1c5dc87269.zip |
New Project Working + Report
Diffstat (limited to 'code/Interpreter2/src/Interpreter/Parser.java')
-rw-r--r-- | code/Interpreter2/src/Interpreter/Parser.java | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/code/Interpreter2/src/Interpreter/Parser.java b/code/Interpreter2/src/Interpreter/Parser.java new file mode 100644 index 0000000..6b55299 --- /dev/null +++ b/code/Interpreter2/src/Interpreter/Parser.java @@ -0,0 +1,179 @@ +package Interpreter; + +import java.util.ArrayList; +import java.util.List; + +public class Parser { + private final List<Token> tokens; + private int currentToken = 0; + + Parser(List<Token> tokens){ + this.tokens=tokens; + } + + List<Statement> parse(){ + List<Statement> statements = new ArrayList<>(); + while (!checkEOF()){ + statements.add(declaration()); + } + return statements; + + } + + private Statement declaration(){ + try{ + if (matchAndAdvance(TokenType.VAR)){ + if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ + if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ + Token varName = getPreviousToken(); + return new Statement.VariableDeclaration(varName); + } + } + } + return statement(); + } catch (Error e){ + currentToken++; + return null; + } + } + + private Statement statement(){ + if (matchAndAdvance(TokenType.PRINT)){ + Expression expression = expression(); + return new Statement.PrintStatement(expression); + } + return expressionStatement(); + } + + + + 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)){ + return new Expression.Literal(getPreviousToken()); + } + + 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(); + } + + +} |