slight typchecking, parsing, grammar cleanup

This commit is contained in:
ChUrl
2021-01-31 22:15:20 +01:00
parent a2b35ad4da
commit b76c458498
6 changed files with 61 additions and 26 deletions

View File

@ -10,12 +10,14 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Repräsentation einer LL(1)-ParsingTabelle.
* Jeder Kombination aus Nichtterminal und Terminal wird ein neues Symbol aus dem Alphabet zugewiesen.
*/
public class ParsingTable {
private static final Pattern X = Pattern.compile("X");
private final Grammar grammar;
private final Map<Entry<String, String>, String> parsetable;
@ -36,6 +38,9 @@ public class ParsingTable {
return this.grammar.getTerminals();
}
// Printing + Overrides
// TODO: This mess
@Override
public String toString() {
final StringBuilder output = new StringBuilder();
@ -74,7 +79,7 @@ public class ParsingTable {
output.append(" ".repeat(margins.get("NTERM")))
.append("| ");
for (String terminal : inputSymbols) {
format.format(X.matcher("%-Xs ").replaceAll(String.valueOf(margins.get(terminal))), terminal);
format.format("%-Xs ".replace("X", String.valueOf(margins.get(terminal))), terminal);
}
output.append("|\n");
@ -88,11 +93,11 @@ public class ParsingTable {
.append("\n");
for (String nonterminal : this.grammar.getNonterminals()) {
format.format(X.matcher("%-Xs| ").replaceAll(String.valueOf(margins.get("NTERM"))), nonterminal);
format.format("%-Xs| ".replace("X", String.valueOf(margins.get("NTERM"))), nonterminal);
for (String terminal : inputSymbols) {
final String prod = this.parsetable.get(new SimpleEntry<>(nonterminal, terminal));
format.format(X.matcher("%-Xs ").replaceAll(String.valueOf(margins.get(terminal))), prod == null ? " ".repeat(9) : prod);
format.format("%-Xs ".replace("X", String.valueOf(margins.get(terminal))), prod == null ? " ".repeat(9) : prod);
}
output.append("|\n");
}

View File

@ -24,7 +24,7 @@ public class StupsParser {
}
public static StupsParser fromGrammar(Grammar grammar) {
final GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
final GrammarAnalyzer analyzer = GrammarAnalyzer.fromGrammar(grammar);
return new StupsParser(analyzer.getTable());
}

View File

@ -16,16 +16,25 @@ import static util.Logger.log;
import static util.Logger.logIfTrue;
import static util.Logger.logNullable;
public class GrammarAnalyzer {
public final class GrammarAnalyzer {
private final Grammar grammar;
/**
* Das first-Set enthält für jedes Nichtterminalsymbol alle Terminalsymbole, die als erstes bei diesen
* Nichtterminal auftreten können.
*/
private final Map<String, Set<String>> first;
/**
* Das follow-Set enhält für jedes Nichtterminalsymbol alle Terminalsymbole, die direkt auf dieses
* Nichtterminal folgen können.
*/
private final Map<String, Set<String>> follow;
private final ParsingTable table;
public GrammarAnalyzer(Grammar grammar) {
private GrammarAnalyzer(Grammar grammar) {
this.grammar = grammar;
log("Analyzing Grammar:\n");
@ -41,6 +50,10 @@ public class GrammarAnalyzer {
System.out.println("Grammar analysis successful.");
}
public static GrammarAnalyzer fromGrammar(Grammar grammar) {
return new GrammarAnalyzer(grammar);
}
private Map<String, Set<String>> initFirst() {
final Map<String, Set<String>> firstOut = new HashMap<>();

View File

@ -2,6 +2,9 @@ package parser.grammar;
import java.util.Objects;
/**
* Repräsentation einer Produktionsregel der Form leftside -> rightside.
*/
public class GrammarRule {
private final String leftside;
@ -20,18 +23,16 @@ public class GrammarRule {
return this.rightside;
}
public String[] getSymbols() {
return this.rightside.split(" ");
}
@Override
public boolean equals(Object obj) {
if (obj instanceof GrammarRule) {
return this.leftside.equals(((GrammarRule) obj).leftside)
&& this.rightside.equals(((GrammarRule) obj).rightside);
public boolean equals(Object o) {
if (this == o) {
return true;
}
return false;
if (o == null || this.getClass() != o.getClass()) {
return false;
}
final GrammarRule that = (GrammarRule) o;
return this.leftside.equals(that.leftside) && this.rightside.equals(that.rightside);
}
@Override

View File

@ -18,7 +18,7 @@ public final class TypeChecker {
private TypeChecker() {}
// TODO: nodeTable?
// TODO: merge nodeTable into typetable?
// Wirft exception bei typeerror, return nodeTable?
public static Map<SyntaxTreeNode, String> validate(SyntaxTree tree) {
final TypeTable table = TypeTable.fromAST(tree);

View File

@ -11,13 +11,27 @@ import java.util.Map;
import static util.Logger.log;
public class TypeTable {
/**
* Speichert die Datentypen von Symbolen und Funktionen in einem Programm.
*/
public final class TypeTable {
/**
* Weist jeder deklarierter Variable ihren Typ zu.
*/
private final Map<String, String> symbolTable;
/**
* Weist jedem Operator einen Rückgabetyp zu.
*/
private final Map<String, String> methodReturnTable;
/**
* Weist jedem Operator die Typen seiner Argumente zu.
*/
private final Map<String, List<String>> methodArgumentTable;
public TypeTable(Map<String, String> symbolTable) {
private TypeTable(Map<String, String> symbolTable) {
this.symbolTable = Collections.unmodifiableMap(symbolTable);
// Enthält die Return-Types der Operatoren
@ -55,18 +69,18 @@ public class TypeTable {
public static TypeTable fromAST(SyntaxTree tree) {
System.out.println(" - Building TypeTable...");
final Map<String, String> tableOut = new HashMap<>();
final Map<String, String> symbolTable = new HashMap<>();
log("Creating TypeTable");
scanTree(tree.getRoot(), tableOut);
initSymbolTable(tree.getRoot(), symbolTable);
log("-".repeat(100));
return new TypeTable(tableOut);
return new TypeTable(symbolTable);
}
private static void scanTree(SyntaxTreeNode root, Map<? super String, String> table) {
private static void initSymbolTable(SyntaxTreeNode root, Map<String, String> table) {
for (SyntaxTreeNode child : root.getChildren()) {
scanTree(child, table);
initSymbolTable(child, table);
}
if ("declaration".equals(root.getName())) {
@ -82,6 +96,8 @@ public class TypeTable {
}
}
// Getters
public String getSymbolType(String sym) {
return this.symbolTable.get(sym);
}