mirror of
https://gitlab.kit.edu/uskyk/typicalc.git
synced 2024-11-08 18:30:42 +00:00
merge
This commit is contained in:
commit
472270bc7d
15
package.json
15
package.json
@ -16,7 +16,6 @@
|
|||||||
"@vaadin/vaadin-combo-box": "5.4.7",
|
"@vaadin/vaadin-combo-box": "5.4.7",
|
||||||
"@vaadin/vaadin-confirm-dialog": "1.3.0",
|
"@vaadin/vaadin-confirm-dialog": "1.3.0",
|
||||||
"@vaadin/vaadin-context-menu": "4.5.0",
|
"@vaadin/vaadin-context-menu": "4.5.0",
|
||||||
"@vaadin/vaadin-cookie-consent": "1.2.0",
|
|
||||||
"@vaadin/vaadin-core-shrinkwrap": "18.0.5",
|
"@vaadin/vaadin-core-shrinkwrap": "18.0.5",
|
||||||
"@vaadin/vaadin-crud": "1.3.0",
|
"@vaadin/vaadin-crud": "1.3.0",
|
||||||
"@vaadin/vaadin-custom-field": "1.3.0",
|
"@vaadin/vaadin-custom-field": "1.3.0",
|
||||||
@ -29,7 +28,6 @@
|
|||||||
"@vaadin/vaadin-icons": "4.3.2",
|
"@vaadin/vaadin-icons": "4.3.2",
|
||||||
"@vaadin/vaadin-item": "2.3.0",
|
"@vaadin/vaadin-item": "2.3.0",
|
||||||
"@vaadin/vaadin-list-box": "1.4.0",
|
"@vaadin/vaadin-list-box": "1.4.0",
|
||||||
"@vaadin/vaadin-login": "1.2.0",
|
|
||||||
"@vaadin/vaadin-lumo-styles": "1.6.0",
|
"@vaadin/vaadin-lumo-styles": "1.6.0",
|
||||||
"@vaadin/vaadin-material-styles": "1.3.2",
|
"@vaadin/vaadin-material-styles": "1.3.2",
|
||||||
"@vaadin/vaadin-menu-bar": "1.2.1",
|
"@vaadin/vaadin-menu-bar": "1.2.1",
|
||||||
@ -37,16 +35,12 @@
|
|||||||
"@vaadin/vaadin-ordered-layout": "1.4.0",
|
"@vaadin/vaadin-ordered-layout": "1.4.0",
|
||||||
"@vaadin/vaadin-progress-bar": "1.3.0",
|
"@vaadin/vaadin-progress-bar": "1.3.0",
|
||||||
"@vaadin/vaadin-radio-button": "1.5.1",
|
"@vaadin/vaadin-radio-button": "1.5.1",
|
||||||
"@vaadin/vaadin-rich-text-editor": "1.3.0",
|
|
||||||
"@vaadin/vaadin-select": "2.4.0",
|
"@vaadin/vaadin-select": "2.4.0",
|
||||||
"@vaadin/vaadin-shrinkwrap": "18.0.5",
|
"@vaadin/vaadin-shrinkwrap": "18.0.5",
|
||||||
"@vaadin/vaadin-split-layout": "4.3.0",
|
"@vaadin/vaadin-split-layout": "4.3.0",
|
||||||
"@vaadin/vaadin-tabs": "3.2.0",
|
"@vaadin/vaadin-tabs": "3.2.0",
|
||||||
"@vaadin/vaadin-text-field": "2.8.2",
|
"@vaadin/vaadin-text-field": "2.8.2",
|
||||||
"@vaadin/vaadin-time-picker": "2.4.0",
|
|
||||||
"@vaadin/vaadin-upload": "4.4.1",
|
|
||||||
"lit-element": "2.3.1",
|
"lit-element": "2.3.1",
|
||||||
"@vaadin/vaadin-date-time-picker": "1.4.0",
|
|
||||||
"@vaadin/form": "./target/flow-frontend/form",
|
"@vaadin/form": "./target/flow-frontend/form",
|
||||||
"@vaadin/vaadin-avatar": "1.0.3",
|
"@vaadin/vaadin-avatar": "1.0.3",
|
||||||
"open": "^7.2.1"
|
"open": "^7.2.1"
|
||||||
@ -85,42 +79,33 @@
|
|||||||
"@vaadin/vaadin-icons": "4.3.2",
|
"@vaadin/vaadin-icons": "4.3.2",
|
||||||
"@vaadin/vaadin-split-layout": "4.3.0",
|
"@vaadin/vaadin-split-layout": "4.3.0",
|
||||||
"@vaadin/vaadin-combo-box": "5.4.7",
|
"@vaadin/vaadin-combo-box": "5.4.7",
|
||||||
"@vaadin/vaadin-cookie-consent": "1.2.0",
|
|
||||||
"@vaadin/vaadin-core-shrinkwrap": "18.0.5",
|
"@vaadin/vaadin-core-shrinkwrap": "18.0.5",
|
||||||
"@vaadin/vaadin-upload": "4.4.1",
|
|
||||||
"@vaadin/vaadin-dialog": "2.5.2",
|
"@vaadin/vaadin-dialog": "2.5.2",
|
||||||
"@vaadin/vaadin-select": "2.4.0",
|
"@vaadin/vaadin-select": "2.4.0",
|
||||||
"@vaadin/vaadin-app-layout": "2.2.0",
|
"@vaadin/vaadin-app-layout": "2.2.0",
|
||||||
"@vaadin/vaadin-item": "2.3.0",
|
"@vaadin/vaadin-item": "2.3.0",
|
||||||
"@vaadin/vaadin-board": "2.2.0",
|
"@vaadin/vaadin-board": "2.2.0",
|
||||||
"@vaadin/vaadin-notification": "1.6.0",
|
"@vaadin/vaadin-notification": "1.6.0",
|
||||||
"@vaadin/vaadin-charts": "7.0.0",
|
|
||||||
"@vaadin/vaadin-grid-pro": "2.2.2",
|
"@vaadin/vaadin-grid-pro": "2.2.2",
|
||||||
"@vaadin/vaadin-progress-bar": "1.3.0",
|
"@vaadin/vaadin-progress-bar": "1.3.0",
|
||||||
"@vaadin/vaadin-shrinkwrap": "18.0.5",
|
"@vaadin/vaadin-shrinkwrap": "18.0.5",
|
||||||
"@vaadin/vaadin-ordered-layout": "1.4.0",
|
"@vaadin/vaadin-ordered-layout": "1.4.0",
|
||||||
"@vaadin/vaadin-login": "1.2.0",
|
|
||||||
"@vaadin/vaadin-button": "2.4.0",
|
"@vaadin/vaadin-button": "2.4.0",
|
||||||
"@vaadin/vaadin-date-picker": "4.4.1",
|
|
||||||
"@vaadin/vaadin-text-field": "2.8.2",
|
"@vaadin/vaadin-text-field": "2.8.2",
|
||||||
"@vaadin/vaadin-menu-bar": "1.2.1",
|
"@vaadin/vaadin-menu-bar": "1.2.1",
|
||||||
"@vaadin/vaadin-form-layout": "2.3.0",
|
"@vaadin/vaadin-form-layout": "2.3.0",
|
||||||
"@vaadin/vaadin-accordion": "1.2.0",
|
|
||||||
"@polymer/iron-list": "3.1.0",
|
"@polymer/iron-list": "3.1.0",
|
||||||
"@vaadin/vaadin-confirm-dialog": "1.3.0",
|
"@vaadin/vaadin-confirm-dialog": "1.3.0",
|
||||||
"@vaadin/vaadin-list-box": "1.4.0",
|
"@vaadin/vaadin-list-box": "1.4.0",
|
||||||
"@vaadin/vaadin-checkbox": "2.5.0",
|
"@vaadin/vaadin-checkbox": "2.5.0",
|
||||||
"@vaadin/vaadin-details": "1.2.0",
|
"@vaadin/vaadin-details": "1.2.0",
|
||||||
"@polymer/iron-icon": "3.0.1",
|
"@polymer/iron-icon": "3.0.1",
|
||||||
"@vaadin/vaadin-time-picker": "2.4.0",
|
|
||||||
"@vaadin/vaadin-context-menu": "4.5.0",
|
"@vaadin/vaadin-context-menu": "4.5.0",
|
||||||
"@vaadin/vaadin-tabs": "3.2.0",
|
"@vaadin/vaadin-tabs": "3.2.0",
|
||||||
"@vaadin/vaadin-radio-button": "1.5.1",
|
"@vaadin/vaadin-radio-button": "1.5.1",
|
||||||
"@vaadin/vaadin-lumo-styles": "1.6.0",
|
"@vaadin/vaadin-lumo-styles": "1.6.0",
|
||||||
"@vaadin/vaadin-material-styles": "1.3.2",
|
"@vaadin/vaadin-material-styles": "1.3.2",
|
||||||
"@vaadin/vaadin-rich-text-editor": "1.3.0",
|
|
||||||
"@vaadin/vaadin-custom-field": "1.3.0",
|
"@vaadin/vaadin-custom-field": "1.3.0",
|
||||||
"@vaadin/vaadin-date-time-picker": "1.4.0",
|
|
||||||
"lit-element": "2.3.1",
|
"lit-element": "2.3.1",
|
||||||
"@vaadin/vaadin-avatar": "1.0.3",
|
"@vaadin/vaadin-avatar": "1.0.3",
|
||||||
"open": "^7.2.1"
|
"open": "^7.2.1"
|
||||||
|
2
pom.xml
2
pom.xml
@ -50,7 +50,7 @@
|
|||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.model.term.VarTerm;
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
import edu.kit.typicalc.model.type.TypeAbstraction;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models the conclusion of an inference rule and consists of a list of type assumptions, a lambda term and a type.
|
* Models the conclusion of an inference rule and consists of a list of type assumptions, a lambda term and a type.
|
||||||
* This class is used in inference steps to represent the conclusion of that specific application of the inference rule.
|
* This class is used in inference steps to represent the conclusion of that specific application of the inference rule.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constrains two types to be equal.
|
* Constrains two types to be equal.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
import edu.kit.typicalc.model.type.TypeVariable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A substitution specifies that some type should be replaced by a different type.
|
* A substitution specifies that some type should be replaced by a different type.
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.step.InferenceStep;
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.model.term.TermVisitor;
|
||||||
|
import edu.kit.typicalc.model.term.VarTerm;
|
||||||
|
import edu.kit.typicalc.model.type.TypeAbstraction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models the proof tree formed when the type of a lambda term is inferred.
|
* Models the proof tree formed when the type of a lambda term is inferred.
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
import edu.kit.typicalc.model.type.TypeVariable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
import edu.kit.typicalc.model.step.InferenceStep;
|
import edu.kit.typicalc.model.step.InferenceStep;
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.model.term.VarTerm;
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
import edu.kit.typicalc.model.type.TypeAbstraction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type inferer is responsible for the whole type inference of a given lambda term, taking
|
* The type inferer is responsible for the whole type inference of a given lambda term, taking
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
import edu.kit.typicalc.model.step.InferenceStep;
|
import edu.kit.typicalc.model.step.InferenceStep;
|
||||||
|
import edu.kit.typicalc.model.type.Type;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.model.term.VarTerm;
|
||||||
|
import edu.kit.typicalc.model.type.TypeAbstraction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instances of this subclass of TypeInferer are used to execute the sub-inference starting in let steps.
|
* Instances of this subclass of TypeInferer are used to execute the sub-inference starting in let steps.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package edu.kit.typicalc.model;
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.type.TypeVariable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides unique type variables on demand.
|
* Provides unique type variables on demand.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model;
|
||||||
|
|
||||||
|
public class UnificationStep {
|
||||||
|
}
|
114
src/main/java/edu/kit/typicalc/model/parser/LambdaLexer.java
Normal file
114
src/main/java/edu/kit/typicalc/model/parser/LambdaLexer.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.parser.Token.TokenType;
|
||||||
|
import edu.kit.typicalc.util.Result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class lexes a term given as String into tokens.
|
||||||
|
* Tokens are lexed one by one as requested by the parser.
|
||||||
|
*/
|
||||||
|
public class LambdaLexer {
|
||||||
|
/**
|
||||||
|
* The given term as a String
|
||||||
|
*/
|
||||||
|
private final String term;
|
||||||
|
/**
|
||||||
|
* current position in the term
|
||||||
|
*/
|
||||||
|
private int pos = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a lexer that lexes the given term
|
||||||
|
* @param term the term to lex
|
||||||
|
*/
|
||||||
|
public LambdaLexer(String term) {
|
||||||
|
this.term = term;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advances the current char to the next char in the term.
|
||||||
|
*/
|
||||||
|
private void advance() {
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lexes and returns the next token.
|
||||||
|
* @return the next token
|
||||||
|
*/
|
||||||
|
public Result<Token, ParseError> nextToken() {
|
||||||
|
while (pos < term.length() && Character.isWhitespace(term.charAt(pos))) {
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
if (pos >= term.length()) {
|
||||||
|
// term ended, return EOF
|
||||||
|
return new Result<>(new Token(TokenType.EOF, "", pos));
|
||||||
|
}
|
||||||
|
Token t;
|
||||||
|
char c = term.charAt(pos);
|
||||||
|
switch (c) {
|
||||||
|
// bunch of single-character tokens
|
||||||
|
case '.':
|
||||||
|
t = new Token(TokenType.DOT, ".", pos);
|
||||||
|
advance();
|
||||||
|
return new Result<>(t);
|
||||||
|
case '(':
|
||||||
|
t = new Token(TokenType.LP, "(", pos);
|
||||||
|
advance();
|
||||||
|
return new Result<>(t);
|
||||||
|
case ')':
|
||||||
|
t = new Token(TokenType.RP, ")", pos);
|
||||||
|
advance();
|
||||||
|
return new Result<>(t);
|
||||||
|
case '=':
|
||||||
|
t = new Token(TokenType.EQ, "=", pos);
|
||||||
|
advance();
|
||||||
|
return new Result<>(t);
|
||||||
|
case '\\':
|
||||||
|
case 'λ':
|
||||||
|
t = new Token(TokenType.LAMBDA, c+"", pos);
|
||||||
|
advance();
|
||||||
|
return new Result<>(t);
|
||||||
|
default:
|
||||||
|
if (Character.isLetter(c)) {
|
||||||
|
// identifier
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
do {
|
||||||
|
sb.append(term.charAt(pos));
|
||||||
|
advance();
|
||||||
|
} while (pos < term.length() && Character.isLetterOrDigit(term.charAt(pos)));
|
||||||
|
String s = sb.toString();
|
||||||
|
TokenType type;
|
||||||
|
switch (s) {
|
||||||
|
case "let":
|
||||||
|
type = TokenType.LET;
|
||||||
|
break;
|
||||||
|
case "in":
|
||||||
|
type = TokenType.IN;
|
||||||
|
break;
|
||||||
|
case "true":
|
||||||
|
type = TokenType.TRUE;
|
||||||
|
break;
|
||||||
|
case "false":
|
||||||
|
type = TokenType.FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = TokenType.VARIABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new Result<>(new Token(type, sb.toString(), pos));
|
||||||
|
} else if (Character.isDigit(c)) {
|
||||||
|
// number literal
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
do {
|
||||||
|
sb.append(term.charAt(pos));
|
||||||
|
advance();
|
||||||
|
} while (pos < term.length() && Character.isDigit(term.charAt(pos)));
|
||||||
|
return new Result<>(new Token(TokenType.NUMBER, sb.toString(), pos));
|
||||||
|
} else {
|
||||||
|
//throw new ParseException("Illegal character '" + term.charAt(pos) + "'");
|
||||||
|
return new Result<>(null, ParseError.UNEXPECTED_CHARACTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
171
src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java
Normal file
171
src/main/java/edu/kit/typicalc/model/parser/LambdaParser.java
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
import edu.kit.typicalc.model.parser.Token.TokenType;
|
||||||
|
import edu.kit.typicalc.model.term.AbsTerm;
|
||||||
|
import edu.kit.typicalc.model.term.AppTerm;
|
||||||
|
import edu.kit.typicalc.model.term.BooleanTerm;
|
||||||
|
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.util.Result;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class LambdaParser {
|
||||||
|
/**
|
||||||
|
* lexer to translate a String into tokens
|
||||||
|
*/
|
||||||
|
private final LambdaLexer lexer;
|
||||||
|
/**
|
||||||
|
* Next token to use while parsing.
|
||||||
|
* The following invariant holds:
|
||||||
|
* When calling a parseX method, token is the first token of X
|
||||||
|
* (as opposed to the last token of the previous construct).
|
||||||
|
*/
|
||||||
|
private Token token;
|
||||||
|
|
||||||
|
private static final Set<TokenType> atomStartTokens
|
||||||
|
= EnumSet.of(TokenType.VARIABLE, TokenType.NUMBER, TokenType.TRUE,
|
||||||
|
TokenType.FALSE, TokenType.LP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a parser with the specified String
|
||||||
|
* @param term String to parse
|
||||||
|
*/
|
||||||
|
public LambdaParser(String term) {
|
||||||
|
this.lexer = new LambdaLexer(term);
|
||||||
|
nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets token to the next available token.
|
||||||
|
*/
|
||||||
|
private Optional<ParseError> nextToken() {
|
||||||
|
Result<Token, ParseError> nextToken = lexer.nextToken();
|
||||||
|
if (nextToken.isError()) {
|
||||||
|
return Optional.of(nextToken.unwrapError());
|
||||||
|
}
|
||||||
|
token = nextToken.unwrap();
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the token type of current token matches the token type given as parameter.
|
||||||
|
* If successful, returns that token and advances to the next token.
|
||||||
|
* Returns false otherwise.
|
||||||
|
* @param type the token type to compare the current token type to
|
||||||
|
*/
|
||||||
|
private boolean expect(TokenType type) {
|
||||||
|
TokenType current = token.getType();
|
||||||
|
nextToken(); // TODO: Fehlerbehandlung
|
||||||
|
return current == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the String given in the constructor as a term.
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a term.
|
||||||
|
* @return the term, or an error
|
||||||
|
*/
|
||||||
|
private Result<LambdaTerm, ParseError> parseTerm() {
|
||||||
|
switch (token.getType()) {
|
||||||
|
case LAMBDA:
|
||||||
|
Result<AbsTerm, ParseError> abs = parseAbstraction();
|
||||||
|
return new Result<>(abs.unwrap(), abs.unwrapError());
|
||||||
|
case LET:
|
||||||
|
Result<LetTerm, ParseError> let = parseLet();
|
||||||
|
return new Result<>(let.unwrap(), let.unwrapError());
|
||||||
|
default:
|
||||||
|
return parseApplication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<AbsTerm, ParseError> parseAbstraction() {
|
||||||
|
nextToken();
|
||||||
|
Result<VarTerm, ParseError> var = parseVar();
|
||||||
|
if (!expect(TokenType.DOT)) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
Result<LambdaTerm, ParseError> body = parseTerm();
|
||||||
|
// TODO: Fehlerbehandlung
|
||||||
|
return new Result(new AbsTerm(var.unwrap(), body.unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an application or constructs of higher precedence.
|
||||||
|
* @return the term, or an error
|
||||||
|
*/
|
||||||
|
private Result<LambdaTerm, ParseError> parseApplication() {
|
||||||
|
LambdaTerm left = parseAtom().unwrap(); // TODO: Fehlerbehandlung
|
||||||
|
while (atomStartTokens.contains(token.getType())) {
|
||||||
|
LambdaTerm atom = parseAtom().unwrap(); // TODO: Fehlerbehandlung
|
||||||
|
left = new AppTerm(left, atom);
|
||||||
|
}
|
||||||
|
return new Result<>(left);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<LetTerm, ParseError> parseLet() {
|
||||||
|
// TODO: Fehlerbehandlung
|
||||||
|
expect(TokenType.LET);
|
||||||
|
VarTerm var = parseVar().unwrap();
|
||||||
|
expect(TokenType.EQ);
|
||||||
|
LambdaTerm def = parseTerm().unwrap();
|
||||||
|
expect(TokenType.IN);
|
||||||
|
LambdaTerm body = parseTerm().unwrap();
|
||||||
|
return new Result<>(new LetTerm(var, def, body));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an atom (variable or number) or a parenthesised expression.
|
||||||
|
* @return the term
|
||||||
|
*/
|
||||||
|
private Result<LambdaTerm, ParseError> parseAtom() {
|
||||||
|
switch (token.getType()) {
|
||||||
|
case VARIABLE:
|
||||||
|
Result<VarTerm, ParseError> var = parseVar();
|
||||||
|
return new Result<>(var.unwrap(), var.unwrapError());
|
||||||
|
case NUMBER:
|
||||||
|
String number = token.getText();
|
||||||
|
int n;
|
||||||
|
try {
|
||||||
|
n = Integer.parseInt(number);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return new Result<>(null, ParseError.UNEXPECTED_CHARACTER);
|
||||||
|
}
|
||||||
|
nextToken();
|
||||||
|
return new Result<>(new IntegerTerm(n));
|
||||||
|
case TRUE:
|
||||||
|
case FALSE:
|
||||||
|
String boolText = token.getText();
|
||||||
|
boolean b = Boolean.parseBoolean(boolText);
|
||||||
|
nextToken();
|
||||||
|
return new Result<>(new BooleanTerm(b));
|
||||||
|
default:
|
||||||
|
expect(TokenType.LP);
|
||||||
|
Result<LambdaTerm, ParseError> term = parseTerm();
|
||||||
|
expect(TokenType.RP);
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<VarTerm, ParseError> parseVar() {
|
||||||
|
String s = token.getText();
|
||||||
|
if (!expect(TokenType.VARIABLE)) {
|
||||||
|
return new Result<>(null, ParseError.UNEXPECTED_TOKEN);
|
||||||
|
}
|
||||||
|
return new Result<>(new VarTerm(s));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
public enum ParseError {
|
||||||
|
UNEXPECTED_TOKEN,
|
||||||
|
TOO_MANY_TOKENS,
|
||||||
|
UNEXPECTED_CHARACTER
|
||||||
|
}
|
78
src/main/java/edu/kit/typicalc/model/parser/Token.java
Normal file
78
src/main/java/edu/kit/typicalc/model/parser/Token.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A token of the Prolog language.
|
||||||
|
*/
|
||||||
|
public class Token {
|
||||||
|
/**
|
||||||
|
* Used to distinguish what kind of token we have.
|
||||||
|
* Most of them stand for exactly one character.
|
||||||
|
* VARIABLE and NUMBER have a regular expression associated with them.
|
||||||
|
* EOF is a special token to indicate that the end of file is reached.
|
||||||
|
*/
|
||||||
|
enum TokenType {
|
||||||
|
LAMBDA, // λ or a backslash
|
||||||
|
VARIABLE, // [a-z][a-zA-Z0-9]* except "let" or "in" or constants
|
||||||
|
LET, // let
|
||||||
|
IN, // in
|
||||||
|
TRUE, // true
|
||||||
|
FALSE, // false
|
||||||
|
NUMBER, // [0-9]+
|
||||||
|
LP, // (
|
||||||
|
RP, // )
|
||||||
|
DOT, // .
|
||||||
|
EQ, // =
|
||||||
|
EOF // pseudo token if end of file is reached
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token type of this Token
|
||||||
|
*/
|
||||||
|
private final TokenType type;
|
||||||
|
/**
|
||||||
|
* the text of this token in the source code
|
||||||
|
*/
|
||||||
|
private final String text;
|
||||||
|
private final int pos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a token.
|
||||||
|
* @param type the token type
|
||||||
|
* @param text text of this token in the source code
|
||||||
|
* @param pos position this token begins
|
||||||
|
*/
|
||||||
|
public Token(TokenType type, String text, int pos) {
|
||||||
|
this.type = type;
|
||||||
|
this.text = text;
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the token type
|
||||||
|
* @return token type
|
||||||
|
*/
|
||||||
|
public TokenType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text of this token in the source code
|
||||||
|
* @return text of this token in the source code
|
||||||
|
*/
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position this token is in
|
||||||
|
* @return position this token is in
|
||||||
|
*/
|
||||||
|
public int getPos() {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return type + "(\"" + text + "\")";
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,4 @@ public abstract class InferenceStep {
|
|||||||
*/
|
*/
|
||||||
public abstract void accept(StepVisitor stepVisitor);
|
public abstract void accept(StepVisitor stepVisitor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
7
src/main/java/edu/kit/typicalc/model/term/AbsTerm.java
Normal file
7
src/main/java/edu/kit/typicalc/model/term/AbsTerm.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class AbsTerm extends LambdaTerm {
|
||||||
|
public AbsTerm(VarTerm var, LambdaTerm body) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
6
src/main/java/edu/kit/typicalc/model/term/AppTerm.java
Normal file
6
src/main/java/edu/kit/typicalc/model/term/AppTerm.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class AppTerm extends LambdaTerm {
|
||||||
|
public AppTerm(LambdaTerm left, LambdaTerm atom) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class BooleanTerm extends ConstTerm {
|
||||||
|
public BooleanTerm(boolean value) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
4
src/main/java/edu/kit/typicalc/model/term/ConstTerm.java
Normal file
4
src/main/java/edu/kit/typicalc/model/term/ConstTerm.java
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class ConstTerm extends LambdaTerm {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class IntegerTerm extends ConstTerm {
|
||||||
|
public IntegerTerm(int value) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class LambdaTerm {
|
||||||
|
}
|
6
src/main/java/edu/kit/typicalc/model/term/LetTerm.java
Normal file
6
src/main/java/edu/kit/typicalc/model/term/LetTerm.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class LetTerm extends LambdaTerm {
|
||||||
|
public LetTerm(VarTerm var, LambdaTerm def, LambdaTerm body) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public interface TermVisitor {
|
||||||
|
}
|
7
src/main/java/edu/kit/typicalc/model/term/VarTerm.java
Normal file
7
src/main/java/edu/kit/typicalc/model/term/VarTerm.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package edu.kit.typicalc.model.term;
|
||||||
|
|
||||||
|
public class VarTerm extends LambdaTerm {
|
||||||
|
public VarTerm(String s) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
4
src/main/java/edu/kit/typicalc/model/type/Type.java
Normal file
4
src/main/java/edu/kit/typicalc/model/type/Type.java
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.type;
|
||||||
|
|
||||||
|
public abstract class Type {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.type;
|
||||||
|
|
||||||
|
public class TypeAbstraction {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package edu.kit.typicalc.model.type;
|
||||||
|
|
||||||
|
public class TypeVariable {
|
||||||
|
}
|
28
src/main/java/edu/kit/typicalc/util/Result.java
Normal file
28
src/main/java/edu/kit/typicalc/util/Result.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package edu.kit.typicalc.util;
|
||||||
|
|
||||||
|
public class Result<T, E> {
|
||||||
|
private final T value;
|
||||||
|
private final E error;
|
||||||
|
|
||||||
|
public Result(T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result(T value, E error) { // TODO: Java does not allow both constructors otherwise
|
||||||
|
this.value = value;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isError() {
|
||||||
|
return error != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T unwrap() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E unwrapError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user