This commit is contained in:
Johanna Stuber 2021-01-28 10:17:54 +01:00
commit cd3612b60b
4 changed files with 98 additions and 2 deletions

View File

@ -3,9 +3,13 @@ package edu.kit.typicalc.model.parser;
import edu.kit.typicalc.model.parser.Token.TokenType;
import edu.kit.typicalc.util.Result;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* This class lexes a term given as String into tokens.
* Tokens are lexed one by one as requested by the parser.
* Tokens are lexed all at once (to catch errors early),
* and passed to the parser on demand.
*/
public class LambdaLexer {
/**
@ -16,6 +20,7 @@ public class LambdaLexer {
* current position in the term
*/
private int pos = 0;
private Result<Deque<Token>, ParseError> result;
/**
* Constructs a lexer that lexes the given term
@ -23,6 +28,24 @@ public class LambdaLexer {
*/
public LambdaLexer(String term) {
this.term = term;
tokenize();
}
private void tokenize() {
Deque<Token> tokens = new ArrayDeque<>();
while (true) {
Result<Token, ParseError> token = parseNextToken();
if (token.isError()) {
result = new Result<>(null, token.unwrapError());
return;
}
Token value = token.unwrap();
tokens.add(value);
if (value.getType() == TokenType.EOF) {
break;
}
}
result = new Result<>(tokens);
}
/**
@ -33,10 +56,24 @@ public class LambdaLexer {
}
/**
* Lexes and returns the next token.
* Returns the next token and advances the lexer position.
* @return the next token
*/
public Result<Token, ParseError> nextToken() {
if (result.isError()) {
return new Result<>(null, result.unwrapError());
}
Deque<Token> tokens = result.unwrap();
if (!tokens.isEmpty()) {
Token token = tokens.removeFirst();
return new Result<>(token);
} else {
return new Result<>(new Token(TokenType.EOF, "", 0));
}
}
public Result<Token, ParseError> parseNextToken() {
while (pos < term.length() && Character.isWhitespace(term.charAt(pos))) {
advance();
}

View File

@ -2,6 +2,8 @@ package edu.kit.typicalc.model.term;
import edu.kit.typicalc.model.type.NamedType;
import java.util.Objects;
/**
* Representation of a constant integer lambda term: e.g. -1, 0 or 16.
*/
@ -25,4 +27,21 @@ public class IntegerTerm extends ConstTerm {
public String toString() {
return Integer.toString(value);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
IntegerTerm that = (IntegerTerm) o;
return value == that.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}

View File

@ -5,6 +5,7 @@ import edu.kit.typicalc.model.type.Type;
import edu.kit.typicalc.model.type.TypeAbstraction;
import java.util.Map;
import java.util.Objects;
/**
* Representation of a let term with its variable, the lambda term assigned
@ -62,4 +63,23 @@ public class LetTerm extends LambdaTerm {
public LambdaTerm getInner() {
return body;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LetTerm letTerm = (LetTerm) o;
return Objects.equals(variable, letTerm.variable)
&& Objects.equals(definition, letTerm.definition)
&& Objects.equals(body, letTerm.body);
}
@Override
public int hashCode() {
return Objects.hash(variable, definition, body);
}
}

View File

@ -4,8 +4,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.kit.typicalc.model.term.AbsTerm;
import edu.kit.typicalc.model.term.AppTerm;
import edu.kit.typicalc.model.term.ConstTerm;
import edu.kit.typicalc.model.term.IntegerTerm;
import edu.kit.typicalc.model.term.LambdaTerm;
import edu.kit.typicalc.model.term.LetTerm;
import edu.kit.typicalc.model.term.VarTerm;
import edu.kit.typicalc.model.type.NamedType;
import edu.kit.typicalc.util.Result;
import org.junit.jupiter.api.Test;
@ -29,4 +33,20 @@ class LambdaParserTest {
new AppTerm(new AbsTerm(new VarTerm("x"), new VarTerm("x")),
new AbsTerm(new VarTerm("x"), new VarTerm("x"))));
}
@Test
void letTerm() {
LambdaParser parser = new LambdaParser("let id = λx.x in id 1");
assertEquals(parser.parse().unwrap(),
new LetTerm(
new VarTerm("id"),
new AbsTerm(
new VarTerm("x"),
new VarTerm("x")
),
new AppTerm(
new VarTerm("id"),
new IntegerTerm(1)
)
));
}
}