diff options
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator/parsing')
12 files changed, 72 insertions, 28 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java index f959daf..45eca22 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java @@ -24,6 +24,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Assignment; import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement; import no.eliashaugsbakk.kompilator.parsing.node.statement.IdentifierDeclaration; import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement; +import no.eliashaugsbakk.kompilator.tokenization.Position; import no.eliashaugsbakk.kompilator.tokenization.Token; /* @@ -56,7 +57,7 @@ public class Parser { public Parser(List<Token> tokens) { this.tokens = tokens; - this.rootNode = new Program(); + this.rootNode = new Program(null); } public AST parse() throws ParserException { @@ -101,7 +102,7 @@ public class Parser { // must be some other token which is not a statement else { - throw new ParserException(token.line(), token.column(), "Unexpected token: " + token.value()); + throw new ParserException(token.position(), "Unexpected token: " + token.value()); } } @@ -116,7 +117,7 @@ public class Parser { } else if (token.value().contentEquals("skriv")) { return parseExpressionStatement(); } else { - throw new ParserException(token.line(), token.column(), "unknown keyword: " + token.value()); + throw new ParserException(token.position(), "unknown keyword: " + token.value()); } } @@ -129,7 +130,7 @@ public class Parser { Expression expression = parseExpression(); expectSemicolon(); - return new ExpressionStatement(expression); + return new ExpressionStatement(expression.position, expression); } private Statement parseIdentifierStatement() throws ParserException { @@ -145,23 +146,23 @@ public class Parser { current--; // rewind to identifier Expression expr = parseFunctionCall(); expectSemicolon(); - return new ExpressionStatement(expr); + return new ExpressionStatement(expr.position, expr); } else { - throw new ParserException(next.line(), next.column(), "Unexpected token after identifier: " + next.value()); + throw new ParserException(next.position(), "Unexpected token after identifier: " + next.value()); } } private Statement parseDeclaration(boolean isMutable) throws ParserException { Token nameToken = tokens.get(current); if (nameToken.type() != IDENTIFIER) { - throw new ParserException(nameToken.line(), nameToken.column(), + throw new ParserException(nameToken.position(), "Expected identifier after declaration keyword, got: " + nameToken.value()); } String identifier = nameToken.value(); current++; // consume identifier if (tokens.get(current).type() != COLON) { - throw new ParserException(tokens.get(current).line(), tokens.get(current).column(), + throw new ParserException(tokens.get(current).position(), "Expected : after identifier in declaration"); } current++; // skip : @@ -175,7 +176,7 @@ public class Parser { } expectSemicolon(); - return new IdentifierDeclaration(identifier, type, initializer, isMutable); + return new IdentifierDeclaration(nameToken.position(), identifier, type, initializer, isMutable); } private Statement parseAssignment(String identifier) throws ParserException { @@ -185,13 +186,13 @@ public class Parser { Expression value = parseExpression(); expectSemicolon(); - return new Assignment(identifier, value); + return new Assignment(value.position, identifier, value); } private Type parseType() throws ParserException { Token token = tokens.get(current); if (token.type() != TYPE) { - throw new ParserException(token.line(), token.column(), + throw new ParserException(token.position(), "Expected type, got: " + token.value()); } current++; @@ -217,32 +218,33 @@ public class Parser { current++; if (token.type() == STRING_LITERAL) { - return new StringLiteral(token.value()); + return new StringLiteral(token.position(), token.value()); } else if (token.type() == IDENTIFIER || token.type() == KEYWORD) { // could be function call or just identifier reference if (current < tokens.size() && tokens.get(current).type() == LPAREN) { current--; return parseFunctionCall(); } - return new Identifier(token.value()); + return new Identifier(token.position(), token.value()); } else { - throw new ParserException(token.line(), token.column(), + throw new ParserException(token.position(), "Unexpected token: " + token.value() + ". Expected an expression"); } } private FunctionCall parseFunctionCall() throws ParserException { - String name = tokens.get(current).value(); + Token token = tokens.get(current); + String name = token.value(); current++; List<Expression> arguments = parseFunctionArguments(); - return new FunctionCall(name, arguments); + return new FunctionCall(token.position(), name, arguments); } private List<Expression> parseFunctionArguments() throws ParserException { List<Expression> arguments = new ArrayList<>(); if (tokens.get(current).type() != LPAREN) { - throw new ParserException(tokens.get(current).line(), tokens.get(current).column(), + throw new ParserException(tokens.get(current).position(), "Expected ("); } current++; // skip ( @@ -256,7 +258,7 @@ public class Parser { } if (current >= tokens.size() || tokens.get(current).type() != RPAREN) { - throw new ParserException(tokens.get(current).line(), tokens.get(current).column(), + throw new ParserException(tokens.get(current).position(), "Expected )"); } current++; // skip ) @@ -266,9 +268,9 @@ public class Parser { private void expectSemicolon() throws ParserException { if (current >= tokens.size()) { - throw new ParserException(-1, -1, "Expected ;"); + throw new ParserException(null, "Expected ;"); } else if (tokens.get(current).type() != SEMICOLON) { - throw new ParserException(tokens.get(current).line(), tokens.get(current).column(), + throw new ParserException(tokens.get(current).position(), "Expected: ;"); } current++; diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java index ac96a5c..892cd7b 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java @@ -1,7 +1,15 @@ package no.eliashaugsbakk.kompilator.parsing; +import no.eliashaugsbakk.kompilator.tokenization.Position; + public class ParserException extends Exception { - public ParserException(int line, int column, String message) { - super(line + ":" + column + ", " + message); + public ParserException(Position position, String message) { + String pos; + if (position == null) { + pos = "unknown position"; + } else { + pos = position.line() + ":" + position.column(); + } + super(pos + ", " + message); } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java index 1eb201c..c825ea9 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java @@ -1,7 +1,15 @@ package no.eliashaugsbakk.kompilator.parsing.node; +import no.eliashaugsbakk.kompilator.tokenization.Position; + /** * Base class for all nodes in the Abstract Syntax Tree. */ public abstract class ASTNode { + public final Position position; + + + public ASTNode(Position position) { + this.position = position; + } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java index d61654f..0fcf09e 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java @@ -3,6 +3,7 @@ package no.eliashaugsbakk.kompilator.parsing.node; import java.util.ArrayList; import java.util.List; import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * Root node of the AST. Contains all top-level statements. @@ -10,6 +11,10 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement; public class Program extends ASTNode { public final List<Statement> statements = new ArrayList<>(); + public Program(Position position) { + super(position); + } + public void addStatement(Statement statement) { this.statements.add(statement); } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java index 18fc585..d50e632 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java @@ -1,6 +1,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression; import no.eliashaugsbakk.kompilator.parsing.node.ASTNode; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * Base class for all expression nodes. @@ -14,4 +15,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.ASTNode; * - myFunction() (function call expression) */ public abstract class Expression extends ASTNode { + public Expression(Position position) { + super(position); + } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java index e18063b..f9aea4f 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java @@ -2,6 +2,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression; import java.util.List; import no.eliashaugsbakk.kompilator.parsing.Type; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * Represents a function call statement (e.g., print("Hello, world")). @@ -10,7 +11,8 @@ public class FunctionCall extends Expression { public final String functionName; public final List<Expression> arguments; - public FunctionCall(String functionName, List<Expression> arguments) { + public FunctionCall(Position position, String functionName, List<Expression> arguments) { + super(position); this.functionName = functionName; this.arguments = arguments; } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java index 91607f8..f899ef3 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java @@ -1,12 +1,15 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression; +import no.eliashaugsbakk.kompilator.tokenization.Position; + /** * Resolves to a variable's value */ public class Identifier extends Expression { public final String name; - public Identifier(String name) { + public Identifier(Position position, String name) { + super(position); this.name = name; } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java index 82402ed..8238880 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java @@ -1,6 +1,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression.literal; import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * Represents a string literal expression (e.g., "Hello, World"). @@ -8,7 +9,8 @@ import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; public class StringLiteral extends Expression { public final String value; - public StringLiteral(String value) { + public StringLiteral(Position position, String value) { + super(position); this.value = value; } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java index 01d207d..7b48c83 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java @@ -1,12 +1,14 @@ package no.eliashaugsbakk.kompilator.parsing.node.statement; import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; +import no.eliashaugsbakk.kompilator.tokenization.Position; public class Assignment extends Statement { public final String identifier; public final Expression expression; - public Assignment(String identifier, Expression expression) { + public Assignment(Position position, String identifier, Expression expression) { + super(position); this.identifier = identifier; this.expression = expression; } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java index e46b691..ce900a7 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java @@ -1,6 +1,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.statement; import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * A statement which holds an expression. @@ -9,7 +10,8 @@ import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; */ public class ExpressionStatement extends Statement { public final Expression expression; - public ExpressionStatement(Expression expression) { + public ExpressionStatement(Position position, Expression expression) { + super(position); this.expression = expression; } } diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java index 69b0f1b..0659bca 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java @@ -2,6 +2,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.statement; import no.eliashaugsbakk.kompilator.parsing.Type; import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression; +import no.eliashaugsbakk.kompilator.tokenization.Position; public class IdentifierDeclaration extends Statement { // identifier name: [my_var]: type = 4; @@ -16,7 +17,8 @@ public class IdentifierDeclaration extends Statement { public final boolean mutable; - public IdentifierDeclaration(String identifier, Type type, Expression initializer, boolean mutable) { + public IdentifierDeclaration(Position position, String identifier, Type type, Expression initializer, boolean mutable) { + super(position); this.identifier = identifier; this.type = type; this.initializer = initializer; diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java index aed21ad..5ab16a3 100644 --- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java +++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java @@ -1,6 +1,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.statement; import no.eliashaugsbakk.kompilator.parsing.node.ASTNode; +import no.eliashaugsbakk.kompilator.tokenization.Position; /** * Base class for all statement nodes. @@ -14,4 +15,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.ASTNode; * - if (x > 0) { } (conditional statement) */ public abstract class Statement extends ASTNode { + protected Statement(Position position) { + super(position); + } } |
