summaryrefslogtreecommitdiffstats
path: root/code/Interpreter/Parser.java
diff options
context:
space:
mode:
Diffstat (limited to 'code/Interpreter/Parser.java')
-rw-r--r--code/Interpreter/Parser.java179
1 files changed, 179 insertions, 0 deletions
diff --git a/code/Interpreter/Parser.java b/code/Interpreter/Parser.java
new file mode 100644
index 0000000..6b55299
--- /dev/null
+++ b/code/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();
+ }
+
+
+}