From b76c45849898c5074ac2d761557a7f2da80decf4 Mon Sep 17 00:00:00 2001 From: ChUrl Date: Sun, 31 Jan 2021 22:15:20 +0100 Subject: [PATCH] slight typchecking, parsing, grammar cleanup --- src/main/java/parser/ParsingTable.java | 15 ++++++---- src/main/java/parser/StupsParser.java | 2 +- .../java/parser/grammar/GrammarAnalyzer.java | 17 +++++++++-- src/main/java/parser/grammar/GrammarRule.java | 21 ++++++------- src/main/java/typechecker/TypeChecker.java | 2 +- src/main/java/typechecker/TypeTable.java | 30 ++++++++++++++----- 6 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/main/java/parser/ParsingTable.java b/src/main/java/parser/ParsingTable.java index b6fb19d..a6d3ab4 100644 --- a/src/main/java/parser/ParsingTable.java +++ b/src/main/java/parser/ParsingTable.java @@ -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, 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"); } diff --git a/src/main/java/parser/StupsParser.java b/src/main/java/parser/StupsParser.java index 326cd9c..c95fea7 100644 --- a/src/main/java/parser/StupsParser.java +++ b/src/main/java/parser/StupsParser.java @@ -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()); } diff --git a/src/main/java/parser/grammar/GrammarAnalyzer.java b/src/main/java/parser/grammar/GrammarAnalyzer.java index 5245dcb..4c056e0 100644 --- a/src/main/java/parser/grammar/GrammarAnalyzer.java +++ b/src/main/java/parser/grammar/GrammarAnalyzer.java @@ -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> first; + + /** + * Das follow-Set enhält für jedes Nichtterminalsymbol alle Terminalsymbole, die direkt auf dieses + * Nichtterminal folgen können. + */ private final Map> 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> initFirst() { final Map> firstOut = new HashMap<>(); diff --git a/src/main/java/parser/grammar/GrammarRule.java b/src/main/java/parser/grammar/GrammarRule.java index ff950cb..c842c91 100644 --- a/src/main/java/parser/grammar/GrammarRule.java +++ b/src/main/java/parser/grammar/GrammarRule.java @@ -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 diff --git a/src/main/java/typechecker/TypeChecker.java b/src/main/java/typechecker/TypeChecker.java index 214aeff..8a36750 100644 --- a/src/main/java/typechecker/TypeChecker.java +++ b/src/main/java/typechecker/TypeChecker.java @@ -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 validate(SyntaxTree tree) { final TypeTable table = TypeTable.fromAST(tree); diff --git a/src/main/java/typechecker/TypeTable.java b/src/main/java/typechecker/TypeTable.java index d0b35e3..28305f5 100644 --- a/src/main/java/typechecker/TypeTable.java +++ b/src/main/java/typechecker/TypeTable.java @@ -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 symbolTable; + + /** + * Weist jedem Operator einen Rückgabetyp zu. + */ private final Map methodReturnTable; + + /** + * Weist jedem Operator die Typen seiner Argumente zu. + */ private final Map> methodArgumentTable; - public TypeTable(Map symbolTable) { + private TypeTable(Map 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 tableOut = new HashMap<>(); + final Map 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 table) { + private static void initSymbolTable(SyntaxTreeNode root, Map 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); }