Skip to content

Commit

Permalink
Add integer literal parse support
Browse files Browse the repository at this point in the history
  • Loading branch information
dilanSachi committed Jan 26, 2025
1 parent 7f1a306 commit 68d4244
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package fi.helsinki.compiler.exceptions;

public class ParserException extends Exception {

public ParserException(String message) {
super(message);
}
}
23 changes: 23 additions & 0 deletions src/main/java/fi/helsinki/compiler/parser/BinaryOp.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
package fi.helsinki.compiler.parser;

import fi.helsinki.compiler.tokenizer.Token;

public class BinaryOp implements Expression {
private Expression left;
private Token operatorToken;
private Expression right;

public BinaryOp(Expression left, Token operatorToken, Expression right) {
this.left = left;
this.operatorToken = operatorToken;
this.right = right;
}

public Expression getLeft() {
return left;
}

public Token getOperatorToken() {
return operatorToken;
}

public Expression getRight() {
return right;
}
}
12 changes: 11 additions & 1 deletion src/main/java/fi/helsinki/compiler/parser/Identifier.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
package fi.helsinki.compiler.parser;

public class Identifier {
public class Identifier implements Expression {

private String name;

public Identifier(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
11 changes: 10 additions & 1 deletion src/main/java/fi/helsinki/compiler/parser/Literal.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package fi.helsinki.compiler.parser;

public class Literal implements Expression {
private

private Integer value;

public Literal(Integer value) {
this.value = value;
}

public Integer getValue() {
return value;
}
}
70 changes: 68 additions & 2 deletions src/main/java/fi/helsinki/compiler/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,78 @@
package fi.helsinki.compiler.parser;

import fi.helsinki.compiler.exceptions.ParserException;
import fi.helsinki.compiler.tokenizer.Token;
import fi.helsinki.compiler.tokenizer.TokenType;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class Parser {

public Expression parse(List<Token> tokens) {
return null;
private List<Token> tokens;
private int tokenPosition;

public Parser(List<Token> tokens) {
this.tokens = tokens;
this.tokenPosition = 0;
}

private Token peek() {
if (tokenPosition == tokens.size()) {
return new Token("", TokenType.END, tokens.getLast().getTokenLocation());
}
return tokens.get(tokenPosition);
}

private Token consume(String... expected) throws ParserException {
Token token = peek();
if (!Arrays.stream(expected).anyMatch(token.getText()::equals)) {
String commaSeparated = Arrays.stream(expected).map(Objects::toString)
.collect(Collectors.joining(", ")).toString();
throw new ParserException(token.getTokenLocation() + ": expected one of: " + commaSeparated);
}
tokenPosition += 1;
return token;
}

public Literal parseIntegerLiteral() throws ParserException {
if (peek().getTokenType() != TokenType.INTEGER_LITERAL) {
throw new ParserException(peek().getTokenLocation() + ": expected an integer literal");
}
Token token = consume();
return new Literal(Integer.valueOf(token.getText()));
}

public Identifier parseIdentifier() throws ParserException {
if (peek().getTokenType() != TokenType.INTEGER_LITERAL) {
throw new ParserException(peek().getTokenLocation() + ": expected an integer literal");
}
Token token = consume();
return new Identifier(token.getText());
}

public Expression parseTerm() throws ParserException {
if (peek().getTokenType() == TokenType.INTEGER_LITERAL) {
return parseIntegerLiteral();
}
if (peek().getTokenType() == TokenType.IDENTIFIER) {
return parseIdentifier();
}
throw new ParserException(peek().getTokenLocation() + ": expected an integer literal or an identifier");
}

public BinaryOp parseExpression() throws ParserException {
Expression left = parseTerm();
while (Arrays.asList("+", "-").contains(peek().getText())) {
Token operatorToken = consume();
Expression right = parseTerm();
left = new BinaryOp(left, operatorToken, right);
}
Token operatorToken = consume("+", "-");
Expression right = parseTerm();
return new BinaryOp(left, operatorToken, right);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ public boolean equals(Object obj) {
tokenLocation.getColumn() == getColumn() &&
tokenLocation.getLine() == getLine();
}

@Override
public String toString() {
return file + ": " + "L->" + line + ", C->" + column;
}
}
3 changes: 2 additions & 1 deletion src/main/java/fi/helsinki/compiler/tokenizer/TokenType.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public enum TokenType {
IDENTIFIER,
STRING_LITERAL,
BOOLEAN_LITERAL,
KEYWORD
KEYWORD,
END
}

0 comments on commit 68d4244

Please sign in to comment.