diff --git a/pom.xml b/pom.xml
index 65684a2..1b207e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
jar
- 1.8
+ 11
UTF-8
UTF-8
@@ -116,6 +116,19 @@
5.7.0
test
+
+
+ org.junit.platform
+ junit-platform-launcher
+ 1.7.0
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ 5.7.0
+ test
+
com.vaadin.componentfactory
tooltip
diff --git a/src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java b/src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java
index b0642d9..64d693c 100644
--- a/src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java
+++ b/src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java
@@ -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 expect(TokenType type) {
TokenType current = token.getType();
- nextToken(); // TODO: Fehlerbehandlung
- return current == type;
+ Optional 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 parse() {
- Result t = parseTerm();
- if (!expect(TokenType.EOF)) {
- return new Result<>(null, ParseError.TOO_MANY_TOKENS);
+ Result t = parseTerm(true);
+ if (t.isError()) {
+ return t;
+ }
+ Optional 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 parseTerm() {
+ private Result parseTerm(boolean next) {
+ if (next) {
+ Optional error = nextToken();
+ if (error.isPresent()) {
+ return new Result<>(null, error.get());
+ }
+ }
switch (token.getType()) {
case LAMBDA:
Result abs = parseAbstraction();
@@ -98,10 +110,11 @@ public class LambdaParser {
private Result parseAbstraction() {
nextToken();
Result var = parseVar();
- if (!expect(TokenType.DOT)) {
- return new Result<>(null, ParseError.UNEXPECTED_TOKEN);
+ Optional next = expect(TokenType.DOT);
+ if (next.isPresent()) {
+ return new Result<>(null, next.get());
}
- Result body = parseTerm();
+ Result 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 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 left = parseAtom();
+ if (left.isError()) {
+ return left;
}
- return new Result<>(left);
+ while (ATOM_START_TOKENS.contains(token.getType())) {
+ Result atom = parseAtom();
+ if (atom.isError()) {
+ return atom;
+ }
+ left = new Result<>(new AppTerm(left.unwrap(), atom.unwrap()));
+ }
+ return left;
}
private Result parseLet() {
// TODO: Fehlerbehandlung
- expect(TokenType.LET);
+ Optional 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 term = parseTerm();
+ Result term = parseTerm(false);
expect(TokenType.RP);
return term;
}
@@ -165,8 +193,9 @@ public class LambdaParser {
private Result parseVar() {
String s = token.getText();
- if (!expect(TokenType.VARIABLE)) {
- return new Result<>(null, ParseError.UNEXPECTED_TOKEN);
+ Optional next = expect(TokenType.VARIABLE);
+ if (next.isPresent()) {
+ return new Result<>(null, next.get());
}
return new Result<>(new VarTerm(s));
}
diff --git a/src/main/java/edu/kit/typicalc/model/parser/ParseError.java b/src/main/java/edu/kit/typicalc/model/parser/ParseError.java
index dc0f6bb..24bfe7e 100644
--- a/src/main/java/edu/kit/typicalc/model/parser/ParseError.java
+++ b/src/main/java/edu/kit/typicalc/model/parser/ParseError.java
@@ -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() {
+
+ }
}
diff --git a/src/test/java/edu/kit/typicalc/model/parser/LambdaParserTest.java b/src/test/java/edu/kit/typicalc/model/parser/LambdaParserTest.java
index dbe7f74..c2f104c 100644
--- a/src/test/java/edu/kit/typicalc/model/parser/LambdaParserTest.java
+++ b/src/test/java/edu/kit/typicalc/model/parser/LambdaParserTest.java
@@ -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());
}
}