grammar update
This commit is contained in:
@ -14,13 +14,14 @@ import static util.Logger.log;
|
|||||||
public final class TypeChecker {
|
public final class TypeChecker {
|
||||||
|
|
||||||
private static final Collection<String> lit = Arrays.asList("INTEGER_LIT", "STRING_LIT", "BOOLEAN_LIT");
|
private static final Collection<String> lit = Arrays.asList("INTEGER_LIT", "STRING_LIT", "BOOLEAN_LIT");
|
||||||
|
private static final Collection<String> unary = Arrays.asList("ADD", "SUB", "NOT");
|
||||||
|
|
||||||
private TypeChecker() {}
|
private TypeChecker() {}
|
||||||
|
|
||||||
// Wirft exception bei typeerror, returned nix
|
// Wirft exception bei typeerror, returned nix
|
||||||
public static void validate(AST tree) {
|
public static void validate(AST tree) {
|
||||||
SymbolTable table = SymbolTable.fromAST(tree);
|
final TypeTable table = TypeTable.fromAST(tree);
|
||||||
Map<ASTNode, String> nodeTable = new HashMap<>();
|
final Map<ASTNode, String> nodeTable = new HashMap<>();
|
||||||
|
|
||||||
log("Typevalidation:");
|
log("Typevalidation:");
|
||||||
validate(tree.getRoot(), table, nodeTable);
|
validate(tree.getRoot(), table, nodeTable);
|
||||||
@ -29,7 +30,7 @@ public final class TypeChecker {
|
|||||||
System.out.println("- Typechecking successful.\n");
|
System.out.println("- Typechecking successful.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validate(ASTNode root, SymbolTable table, Map<ASTNode, String> nodeTable) {
|
private static void validate(ASTNode root, TypeTable table, Map<ASTNode, String> nodeTable) {
|
||||||
for (ASTNode child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
validate(child, table, nodeTable);
|
validate(child, table, nodeTable);
|
||||||
}
|
}
|
||||||
@ -37,42 +38,42 @@ public final class TypeChecker {
|
|||||||
if (lit.contains(root.getName())) {
|
if (lit.contains(root.getName())) {
|
||||||
// NodeTable Eintrag für Literal hinzufügen
|
// NodeTable Eintrag für Literal hinzufügen
|
||||||
|
|
||||||
String literalType = getLiteralType(root.getName());
|
final String literalType = getLiteralType(root.getName());
|
||||||
|
|
||||||
nodeTable.put(root, literalType);
|
nodeTable.put(root, literalType);
|
||||||
return;
|
return;
|
||||||
} else if ("EXPR".equals(root.getName())) {
|
} else if ("expr".equals(root.getName())) {
|
||||||
// NodeTable Eintrag für Expression hinzufügen
|
// NodeTable Eintrag für Expression hinzufügen
|
||||||
|
|
||||||
String exprType = table.getMethodReturnType(root.getValue());
|
final String exprType = table.getMethodReturnType(root.getValue());
|
||||||
|
|
||||||
nodeTable.put(root, exprType);
|
nodeTable.put(root, exprType);
|
||||||
} else if ("PAR_EXPR".equals(root.getName())) {
|
} else if ("par_expr".equals(root.getName())) {
|
||||||
// Nodetable Eintrag für Klammern
|
// Nodetable Eintrag für Klammern
|
||||||
|
|
||||||
ASTNode centerChild = root.getChildren().get(1);
|
final ASTNode centerChild = root.getChildren().get(1);
|
||||||
|
|
||||||
nodeTable.put(root, nodeTable.get(centerChild));
|
nodeTable.put(root, nodeTable.get(centerChild));
|
||||||
} else if ("IDENTIFIER".equals(root.getName())) {
|
} else if ("IDENTIFIER".equals(root.getName())) {
|
||||||
// Nodedtable Eintrag fuer Identifier
|
// Nodedtable Eintrag fuer Identifier
|
||||||
|
|
||||||
String identifierType = table.getSymbolType(root.getValue());
|
final String identifierType = table.getSymbolType(root.getValue());
|
||||||
|
|
||||||
nodeTable.put(root, identifierType);
|
nodeTable.put(root, identifierType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("ASSIGNMENT".equals(root.getName())) {
|
if ("assignment".equals(root.getName())) {
|
||||||
validateAssignment(root, table, nodeTable);
|
validateAssignment(root, table, nodeTable);
|
||||||
} else if ("EXPR".equals(root.getName())) {
|
} else if ("expr".equals(root.getName())) {
|
||||||
validateExpression(root, table, nodeTable);
|
validateExpression(root, table, nodeTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateAssignment(ASTNode root, SymbolTable table, Map<ASTNode, String> nodeTable) {
|
private static void validateAssignment(ASTNode root, TypeTable table, Map<ASTNode, String> nodeTable) {
|
||||||
String identifier = root.getValue();
|
final String identifier = root.getValue();
|
||||||
String identifierType = table.getSymbolType(identifier);
|
final String identifierType = table.getSymbolType(identifier);
|
||||||
ASTNode literalNode = root.getChildren().get(0);
|
final ASTNode literalNode = root.getChildren().get(0);
|
||||||
String literalType = nodeTable.get(literalNode);
|
final String literalType = nodeTable.get(literalNode);
|
||||||
|
|
||||||
log("Validating Assignment: " + identifierType + ": " + identifier + " = " + literalType);
|
log("Validating Assignment: " + identifierType + ": " + identifier + " = " + literalType);
|
||||||
|
|
||||||
@ -83,9 +84,8 @@ public final class TypeChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateExpression(ASTNode root, SymbolTable table, Map<ASTNode, String> nodeTable) {
|
private static void validateExpression(ASTNode root, TypeTable table, Map<ASTNode, String> nodeTable) {
|
||||||
Collection<String> unary = Arrays.asList("ADD", "SUB", "NOT");
|
final String op = root.getValue();
|
||||||
String op = root.getValue();
|
|
||||||
|
|
||||||
log("Validating Expression: " + root.getValue());
|
log("Validating Expression: " + root.getValue());
|
||||||
|
|
||||||
@ -110,11 +110,11 @@ public final class TypeChecker {
|
|||||||
throw new OperatorUsageException("Versuche binären Operator " + op + " mit einem Argument aufzurufen.");
|
throw new OperatorUsageException("Versuche binären Operator " + op + " mit einem Argument aufzurufen.");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> requiredType = table.getMethodArgumentType(op);
|
final List<String> requiredType = table.getMethodArgumentType(op);
|
||||||
for (ASTNode child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
// Jedes Child muss korrekten Typ zurückgeben
|
// Jedes Child muss korrekten Typ zurückgeben
|
||||||
|
|
||||||
String childReturnType = nodeTable.get(child);
|
final String childReturnType = nodeTable.get(child);
|
||||||
|
|
||||||
if (!requiredType.contains(childReturnType)) {
|
if (!requiredType.contains(childReturnType)) {
|
||||||
// Child returned Typ, welcher nicht im SymbolTable als Argumenttyp steht
|
// Child returned Typ, welcher nicht im SymbolTable als Argumenttyp steht
|
||||||
|
|||||||
@ -10,13 +10,13 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static util.Logger.log;
|
import static util.Logger.log;
|
||||||
|
|
||||||
public class SymbolTable {
|
public class TypeTable {
|
||||||
|
|
||||||
private final Map<String, String> symbolTable;
|
private final Map<String, String> symbolTable;
|
||||||
private final Map<String, String> methodReturnTable;
|
private final Map<String, String> methodReturnTable;
|
||||||
private final Map<String, List<String>> methodArgumentTable;
|
private final Map<String, List<String>> methodArgumentTable;
|
||||||
|
|
||||||
public SymbolTable(Map<String, String> symbolTable) {
|
public TypeTable(Map<String, String> symbolTable) {
|
||||||
this.symbolTable = symbolTable;
|
this.symbolTable = symbolTable;
|
||||||
|
|
||||||
// Enthält die Return-Types der Operatoren
|
// Enthält die Return-Types der Operatoren
|
||||||
@ -63,14 +63,14 @@ public class SymbolTable {
|
|||||||
this.methodArgumentTable = argumentTable;
|
this.methodArgumentTable = argumentTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SymbolTable fromAST(AST tree) {
|
public static TypeTable fromAST(AST tree) {
|
||||||
final Map<String, String> tableOut = new HashMap<>();
|
final Map<String, String> tableOut = new HashMap<>();
|
||||||
|
|
||||||
log("Creating SymbolTable");
|
log("Creating TypeTable");
|
||||||
scanTree(tree.getRoot(), tableOut);
|
scanTree(tree.getRoot(), tableOut);
|
||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
|
|
||||||
return new SymbolTable(tableOut);
|
return new TypeTable(tableOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void scanTree(ASTNode root, Map<String, String> table) {
|
private static void scanTree(ASTNode root, Map<String, String> table) {
|
||||||
@ -78,16 +78,15 @@ public class SymbolTable {
|
|||||||
scanTree(child, table);
|
scanTree(child, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("DECLARATION".equals(root.getName())) {
|
if ("declaration".equals(root.getName())) {
|
||||||
ASTNode left = root.getChildren().get(0);
|
final ASTNode child = root.getChildren().get(0);
|
||||||
ASTNode right = root.getChildren().get(1);
|
|
||||||
|
|
||||||
log("Adding Entry " + right.getValue() + " -> " + left.getName());
|
log("Adding Entry " + child.getValue() + " -> " + root.getValue());
|
||||||
String oldEntry = table.put(right.getValue(), left.getName());
|
final String oldEntry = table.put(child.getValue(), root.getValue());
|
||||||
|
|
||||||
if (oldEntry != null) {
|
if (oldEntry != null) {
|
||||||
System.out.println("Line " + root.getLine() + " Symbolerror: [" + right.getValue() + "] already defined");
|
System.out.println("Line " + root.getLine() + " Symbolerror: [" + child.getValue() + "] already defined");
|
||||||
throw new SymbolAlreadyDefinedException("Das Symbol " + right.getValue() + " wurde bereits deklariert.");
|
throw new SymbolAlreadyDefinedException("Das Symbol " + child.getValue() + " wurde bereits deklariert.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user