mirror of
https://gitlab.kit.edu/uskyk/typicalc.git
synced 2024-11-08 10:20:41 +00:00
Include token in ParseError + more error handling
This commit is contained in:
parent
07a7218192
commit
4e5488e1eb
15
pom.xml
15
pom.xml
@ -8,7 +8,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
@ -116,6 +116,19 @@
|
||||
<version>5.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- need these for IntelliJ -->
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-launcher</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<version>5.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin.componentfactory</groupId>
|
||||
<artifactId>tooltip</artifactId>
|
||||
|
@ -37,7 +37,6 @@ public class LambdaParser {
|
||||
*/
|
||||
public LambdaParser(String term) {
|
||||
this.lexer = new LambdaLexer(term);
|
||||
nextToken();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,10 +57,13 @@ public class LambdaParser {
|
||||
* Returns false otherwise.
|
||||
* @param type the token type to compare the current token type to
|
||||
*/
|
||||
private boolean expect(TokenType type) {
|
||||
private Optional<ParseError> expect(TokenType type) {
|
||||
TokenType current = token.getType();
|
||||
nextToken(); // TODO: Fehlerbehandlung
|
||||
return current == type;
|
||||
Optional<ParseError> error = nextToken();
|
||||
if (current != type) {
|
||||
return Optional.of(ParseError.UNEXPECTED_TOKEN.withToken(token));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,9 +71,13 @@ public class LambdaParser {
|
||||
* @return the term given by the String
|
||||
*/
|
||||
public Result<LambdaTerm, ParseError> parse() {
|
||||
Result<LambdaTerm, ParseError> t = parseTerm();
|
||||
if (!expect(TokenType.EOF)) {
|
||||
return new Result<>(null, ParseError.TOO_MANY_TOKENS);
|
||||
Result<LambdaTerm, ParseError> t = parseTerm(true);
|
||||
if (t.isError()) {
|
||||
return t;
|
||||
}
|
||||
Optional<ParseError> next = expect(TokenType.EOF);
|
||||
if (next.isPresent()) {
|
||||
return new Result<>(null, next.get());
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@ -80,7 +86,13 @@ public class LambdaParser {
|
||||
* Parses a term.
|
||||
* @return the term, or an error
|
||||
*/
|
||||
private Result<LambdaTerm, ParseError> parseTerm() {
|
||||
private Result<LambdaTerm, ParseError> parseTerm(boolean next) {
|
||||
if (next) {
|
||||
Optional<ParseError> error = nextToken();
|
||||
if (error.isPresent()) {
|
||||
return new Result<>(null, error.get());
|
||||
}
|
||||
}
|
||||
switch (token.getType()) {
|
||||
case LAMBDA:
|
||||
Result<AbsTerm, ParseError> abs = parseAbstraction();
|
||||
@ -98,10 +110,11 @@ public class LambdaParser {
|
||||
private Result<AbsTerm, ParseError> parseAbstraction() {
|
||||
nextToken();
|
||||
Result<VarTerm, ParseError> var = parseVar();
|
||||
if (!expect(TokenType.DOT)) {
|
||||
return new Result<>(null, ParseError.UNEXPECTED_TOKEN);
|
||||
Optional<ParseError> next = expect(TokenType.DOT);
|
||||
if (next.isPresent()) {
|
||||
return new Result<>(null, next.get());
|
||||
}
|
||||
Result<LambdaTerm, ParseError> body = parseTerm();
|
||||
Result<LambdaTerm, ParseError> body = parseTerm(false);
|
||||
// TODO: Fehlerbehandlung
|
||||
return new Result<>(new AbsTerm(var.unwrap(), body.unwrap()));
|
||||
}
|
||||
@ -111,22 +124,37 @@ public class LambdaParser {
|
||||
* @return the term, or an error
|
||||
*/
|
||||
private Result<LambdaTerm, ParseError> parseApplication() {
|
||||
LambdaTerm left = parseAtom().unwrap(); // TODO: Fehlerbehandlung
|
||||
while (ATOM_START_TOKENS.contains(token.getType())) {
|
||||
LambdaTerm atom = parseAtom().unwrap(); // TODO: Fehlerbehandlung
|
||||
left = new AppTerm(left, atom);
|
||||
Result<LambdaTerm, ParseError> left = parseAtom();
|
||||
if (left.isError()) {
|
||||
return left;
|
||||
}
|
||||
return new Result<>(left);
|
||||
while (ATOM_START_TOKENS.contains(token.getType())) {
|
||||
Result<LambdaTerm, ParseError> atom = parseAtom();
|
||||
if (atom.isError()) {
|
||||
return atom;
|
||||
}
|
||||
left = new Result<>(new AppTerm(left.unwrap(), atom.unwrap()));
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
private Result<LetTerm, ParseError> parseLet() {
|
||||
// TODO: Fehlerbehandlung
|
||||
expect(TokenType.LET);
|
||||
Optional<ParseError> error = expect(TokenType.LET);
|
||||
if (error.isPresent()) {
|
||||
return new Result<>(null, error.get());
|
||||
}
|
||||
VarTerm var = parseVar().unwrap();
|
||||
expect(TokenType.EQ);
|
||||
LambdaTerm def = parseTerm().unwrap();
|
||||
expect(TokenType.IN);
|
||||
LambdaTerm body = parseTerm().unwrap();
|
||||
error = expect(TokenType.EQ);
|
||||
if (error.isPresent()) {
|
||||
return new Result<>(null, error.get());
|
||||
}
|
||||
LambdaTerm def = parseTerm(false).unwrap();
|
||||
error = expect(TokenType.IN);
|
||||
if (error.isPresent()) {
|
||||
return new Result<>(null, error.get());
|
||||
}
|
||||
LambdaTerm body = parseTerm(false).unwrap();
|
||||
return new Result<>(new LetTerm(var, def, body));
|
||||
}
|
||||
|
||||
@ -145,7 +173,7 @@ public class LambdaParser {
|
||||
try {
|
||||
n = Integer.parseInt(number);
|
||||
} catch (NumberFormatException e) {
|
||||
return new Result<>(null, ParseError.UNEXPECTED_CHARACTER);
|
||||
return new Result<>(null, ParseError.UNEXPECTED_CHARACTER.withToken(token));
|
||||
}
|
||||
nextToken();
|
||||
return new Result<>(new IntegerTerm(n));
|
||||
@ -157,7 +185,7 @@ public class LambdaParser {
|
||||
return new Result<>(new BooleanTerm(b));
|
||||
default:
|
||||
expect(TokenType.LP);
|
||||
Result<LambdaTerm, ParseError> term = parseTerm();
|
||||
Result<LambdaTerm, ParseError> term = parseTerm(false);
|
||||
expect(TokenType.RP);
|
||||
return term;
|
||||
}
|
||||
@ -165,8 +193,9 @@ public class LambdaParser {
|
||||
|
||||
private Result<VarTerm, ParseError> parseVar() {
|
||||
String s = token.getText();
|
||||
if (!expect(TokenType.VARIABLE)) {
|
||||
return new Result<>(null, ParseError.UNEXPECTED_TOKEN);
|
||||
Optional<ParseError> next = expect(TokenType.VARIABLE);
|
||||
if (next.isPresent()) {
|
||||
return new Result<>(null, next.get());
|
||||
}
|
||||
return new Result<>(new VarTerm(s));
|
||||
}
|
||||
|
@ -7,11 +7,6 @@ public enum ParseError {
|
||||
*/
|
||||
UNEXPECTED_TOKEN,
|
||||
|
||||
/**
|
||||
* some tokens were remaining after parsing a full lambda term
|
||||
*/
|
||||
TOO_MANY_TOKENS,
|
||||
|
||||
/**
|
||||
* some tokens were required, but not provided
|
||||
*/
|
||||
@ -20,5 +15,23 @@ public enum ParseError {
|
||||
/**
|
||||
* the string contained a character not allowed in that context
|
||||
*/
|
||||
UNEXPECTED_CHARACTER
|
||||
UNEXPECTED_CHARACTER;
|
||||
|
||||
private Token cause;
|
||||
|
||||
public ParseError withToken(Token cause) {
|
||||
this.cause = cause;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the token associated with this error, or null if none
|
||||
*/
|
||||
public Token getCause() { // TODO: document
|
||||
return cause;
|
||||
}
|
||||
|
||||
ParseError() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -85,5 +85,14 @@ class LambdaParserTest {
|
||||
void miscellaneousTerms() {
|
||||
LambdaParser parser = new LambdaParser("");
|
||||
assertEquals(ParseError.TOO_FEW_TOKENS, parser.parse().unwrapError());
|
||||
parser = new LambdaParser("x)");
|
||||
assertEquals(ParseError.UNEXPECTED_TOKEN, parser.parse().unwrapError());
|
||||
System.out.println("parsing ??");
|
||||
parser = new LambdaParser("??");
|
||||
assertEquals(ParseError.UNEXPECTED_CHARACTER, parser.parse().unwrapError());
|
||||
parser = new LambdaParser("123333333333333");
|
||||
assertEquals(ParseError.UNEXPECTED_CHARACTER, parser.parse().unwrapError());
|
||||
parser = new LambdaParser("x 123333333333333");
|
||||
assertEquals(ParseError.UNEXPECTED_CHARACTER, parser.parse().unwrapError());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user