renamings

This commit is contained in:
ChUrl
2020-12-13 15:01:55 +01:00
parent e56e1abc46
commit ed99c71d44
22 changed files with 215 additions and 213 deletions

View File

@ -1,7 +1,7 @@
import lexer.StupsLexer;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Lexer;
import parser.LL1Parser;
import parser.Parser;
import parser.grammar.Grammar;
import java.io.IOException;
@ -50,7 +50,7 @@ public final class StupsCompiler {
return;
}
LL1Parser parser = LL1Parser.fromGrammar(grammar);
Parser parser = Parser.fromGrammar(grammar);
parser.parse(lexer.getAllTokens(), lexer.getVocabulary());

View File

@ -4,13 +4,13 @@ import parser.ast.AST;
import static util.Logger.log;
public class MyParseException extends RuntimeException {
public class ParseException extends RuntimeException {
public MyParseException(String message) {
public ParseException(String message) {
super(message);
}
public MyParseException(String message, AST ast) {
public ParseException(String message, AST ast) {
super(message);
log("\nAST at last state:\n" + ast);

View File

@ -3,9 +3,9 @@ package parser;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.Vocabulary;
import parser.ast.AST;
import parser.ast.Node;
import parser.ast.ASTNode;
import parser.grammar.Grammar;
import parser.grammar.LL1GrammarAnalyzer;
import parser.grammar.GrammarAnalyzer;
import java.io.IOException;
import java.nio.file.Path;
@ -15,27 +15,27 @@ import java.util.List;
import static util.Logger.log;
public class LL1Parser {
public class Parser {
private final LL1ParsingTable parsetable;
private final ParsingTable parsetable;
public LL1Parser(LL1ParsingTable parsetable) {
public Parser(ParsingTable parsetable) {
this.parsetable = parsetable;
}
public static LL1Parser fromGrammar(Path path) throws IOException {
return LL1Parser.fromGrammar(Grammar.fromFile(path));
public static Parser fromGrammar(Path path) throws IOException {
return Parser.fromGrammar(Grammar.fromFile(path));
}
public static LL1Parser fromGrammar(Grammar grammar) {
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar);
return new LL1Parser(analyzer.getTable());
public static Parser fromGrammar(Grammar grammar) {
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
return new Parser(analyzer.getTable());
}
public AST parse(List<? extends Token> token, Vocabulary voc) {
Node root = new Node(this.parsetable.getStartSymbol());
ASTNode root = new ASTNode(this.parsetable.getStartSymbol());
AST tree = new AST(root);
Deque<Node> stack = new ArrayDeque<>();
Deque<ASTNode> stack = new ArrayDeque<>();
stack.push(root);
int inputPosition = 0;
@ -75,24 +75,24 @@ public class LL1Parser {
System.out.println("Syntaxfehler.");
throw new MyParseException("Invalid terminal on stack: " + top, tree);
throw new ParseException("Invalid terminal on stack: " + top, tree);
} else if (prod == null) {
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
System.out.println("Syntaxfehler.");
throw new MyParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
throw new ParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
} else {
// Wenn das Nichtterminal auf dem Stack durch (s)eine Produktion ersetzt werden kann
// Hier wird auch der AST aufgebaut
log("Used: " + top + " -> " + prod);
Node pop = stack.pop();
ASTNode pop = stack.pop();
final String[] split = prod.split(" ");
for (int i = split.length - 1; i >= 0; i--) {
Node node = new Node(split[i]);
ASTNode ASTNode = new ASTNode(split[i]);
if (inputPosition + i < token.size()) {
// Die Schleife geht in der Eingabe weiter
@ -100,12 +100,12 @@ public class LL1Parser {
// Die Token mit semantischem Inhalt auswählen
if ("IDENTIFIER".equals(split[i]) || split[i].endsWith("_LIT")) {
node.setValue(currentTok.getText());
ASTNode.setValue(currentTok.getText());
}
}
stack.push(node);
pop.addChild(node);
stack.push(ASTNode);
pop.addChild(ASTNode);
}
}
}

View File

@ -1,7 +1,7 @@
package parser;
import parser.grammar.Grammar;
import parser.grammar.LL1GrammarAnalyzer;
import parser.grammar.GrammarAnalyzer;
import java.util.AbstractMap.SimpleEntry;
import java.util.Formatter;
@ -12,18 +12,18 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
public class LL1ParsingTable {
public class ParsingTable {
private final Grammar grammar;
private final Map<Entry<String, String>, String> parsetable;
public LL1ParsingTable(Grammar grammar, Map<Entry<String, String>, String> parsetable) {
public ParsingTable(Grammar grammar, Map<Entry<String, String>, String> parsetable) {
this.grammar = grammar;
this.parsetable = parsetable;
}
public static LL1ParsingTable fromGrammar(Grammar grammar) {
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar);
public static ParsingTable fromGrammar(Grammar grammar) {
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
return analyzer.getTable();
}

View File

@ -6,13 +6,13 @@ import java.util.Objects;
public class AST {
private final Node root;
private final ASTNode root;
public AST(Node root) {
public AST(ASTNode root) {
this.root = root;
}
public Node getRoot() {
public ASTNode getRoot() {
return this.root;
}
@ -22,7 +22,7 @@ public class AST {
public void preprocess(Grammar grammar) {
ASTCompacter.clean(this, grammar);
ExpressionBalancer.balance(this);
ASTBalancer.balance(this);
}
@Override

View File

@ -6,9 +6,9 @@ import java.util.Collections;
import static util.Logger.log;
public final class ExpressionBalancer {
public final class ASTBalancer {
private ExpressionBalancer() {}
private ASTBalancer() {}
public static void balance(AST tree) {
flip(tree);
@ -25,8 +25,8 @@ public final class ExpressionBalancer {
flip(tree.getRoot());
}
private static void flip(Node root) {
for (Node child : root.getChildren()) {
private static void flip(ASTNode root) {
for (ASTNode child : root.getChildren()) {
flip(child);
}
@ -41,12 +41,12 @@ public final class ExpressionBalancer {
}
// Es wird solange rotiert bis die letzte "Rotation" durchgeführt wurde
private static void leftPrecedence(Node root) {
for (Node child : root.getChildren()) {
private static void leftPrecedence(ASTNode root) {
for (ASTNode child : root.getChildren()) {
leftPrecedence(child);
}
Node expr = getExpr(root);
ASTNode expr = getExpr(root);
if (expr == null || root.getChildren().size() != 2 || !root.getValue().isEmpty()) {
return;
@ -60,9 +60,9 @@ public final class ExpressionBalancer {
}
// Die Letzte Rotation ist keine richtige Rotation, dort wird false zurückgegeben
private static boolean specialLeftRotate(Node root) {
Node left = root.getChildren().get(0);
Node right = root.getChildren().get(1);
private static boolean specialLeftRotate(ASTNode root) {
ASTNode left = root.getChildren().get(0);
ASTNode right = root.getChildren().get(1);
// Verhindert Wurzel mit nur einem EXPR-Child (nach oben "hängende" Wurzel)
if (endOfExpr(right)) {
@ -72,7 +72,7 @@ public final class ExpressionBalancer {
return false; // Braucht keine weitere Rotation
}
Node insertLeft = new Node(root.getName());
ASTNode insertLeft = new ASTNode(root.getName());
insertLeft.setValue(right.getValue()); // Operation wird linksvererbt
insertLeft.setChildren(left, right.getChildren().get(0));
@ -82,8 +82,8 @@ public final class ExpressionBalancer {
return true;
}
private static Node getExpr(Node root) {
for (Node child : root.getChildren()) {
private static ASTNode getExpr(ASTNode root) {
for (ASTNode child : root.getChildren()) {
if (child.getName().equals("EXPR")) {
return child;
}
@ -92,7 +92,7 @@ public final class ExpressionBalancer {
return null;
}
private static boolean endOfExpr(Node root) {
private static boolean endOfExpr(ASTNode root) {
return root.getChildren().size() == 1;
}
@ -108,8 +108,8 @@ public final class ExpressionBalancer {
operatorPrecedence(tree.getRoot());
}
public static void operatorPrecedence(Node root) {
for (Node child : root.getChildren()) {
public static void operatorPrecedence(ASTNode root) {
for (ASTNode child : root.getChildren()) {
operatorPrecedence(child);
}
@ -118,8 +118,8 @@ public final class ExpressionBalancer {
}
}
private static boolean preceding(Node root) {
Node op = getExpr(root);
private static boolean preceding(ASTNode root) {
ASTNode op = getExpr(root);
if (op == null || !root.getName().equals("EXPR") || root.getValue().isEmpty()) {
return false;
@ -134,11 +134,11 @@ public final class ExpressionBalancer {
|| (logHigh.contains(root.getValue()) && logLow.contains(op.getValue()));
}
private static void simpleRightRotate(Node root) {
Node left = root.getChildren().get(0);
Node right = root.getChildren().get(1);
private static void simpleRightRotate(ASTNode root) {
ASTNode left = root.getChildren().get(0);
ASTNode right = root.getChildren().get(1);
Node insertRight = new Node(root.getName());
ASTNode insertRight = new ASTNode(root.getName());
insertRight.setValue(root.getValue());
insertRight.setChildren(left.getChildren().get(1), right);

View File

@ -53,11 +53,11 @@ public final class ASTCompacter {
return compacted;
}
private static int compact(Node root, Grammar grammar) {
private static int compact(ASTNode root, Grammar grammar) {
int compacted = 0;
Collection<Node> toRemove = new HashSet<>();
Collection<ASTNode> toRemove = new HashSet<>();
for (Node child : root.getChildren()) {
for (ASTNode child : root.getChildren()) {
if (grammar.hasCompact(root.getName())
&& root.getChildren().size() == 1) {
@ -91,11 +91,11 @@ public final class ASTCompacter {
return removed;
}
private static int removeNullable(Node root, Grammar grammar) {
private static int removeNullable(ASTNode root, Grammar grammar) {
int removed = 0;
Collection<Node> toRemove = new HashSet<>();
Collection<ASTNode> toRemove = new HashSet<>();
for (Node child : root.getChildren()) {
for (ASTNode child : root.getChildren()) {
if (grammar.hasNullable(child.getName())
&& child.getValue().isEmpty()
&& !child.hasChildren()) {
@ -125,11 +125,11 @@ public final class ASTCompacter {
return removed;
}
private static int removeEpsilon(Node root, Grammar grammar) {
private static int removeEpsilon(ASTNode root, Grammar grammar) {
int removed = 0;
Collection<Node> toRemove = new HashSet<>();
Collection<ASTNode> toRemove = new HashSet<>();
for (Node child : root.getChildren()) {
for (ASTNode child : root.getChildren()) {
if (child.getName().equals(grammar.getEpsilonSymbol()) && !child.hasChildren()) {
log("Removing " + root.getName() + " -> " + child.getName());
toRemove.add(child);
@ -155,13 +155,13 @@ public final class ASTCompacter {
return removed;
}
private static int removeRedundant(Node root) {
private static int removeRedundant(ASTNode root) {
int removed = 0;
Collection<Node> toRemove = new HashSet<>();
Collection<ASTNode> toRemove = new HashSet<>();
Collection<String> removable = Arrays.asList("IF", "ELSE", "WHILE", "ASSIGN");
for (Node child : root.getChildren()) {
for (ASTNode child : root.getChildren()) {
if (removable.contains(child.getName()) && !child.hasChildren()) {
log("Removing " + root.getName() + " -> " + child.getName());
toRemove.add(child);
@ -182,7 +182,7 @@ public final class ASTCompacter {
log("-".repeat(100));
}
private static void renameEXPR(Node root) {
private static void renameEXPR(ASTNode root) {
String newName = switch (root.getName()) {
case "EXPR_2", "EXPR_F" -> "EXPR";
default -> root.getName();
@ -194,7 +194,7 @@ public final class ASTCompacter {
root.setName(newName);
for (Node child : root.getChildren()) {
for (ASTNode child : root.getChildren()) {
renameEXPR(child);
}
}
@ -206,12 +206,12 @@ public final class ASTCompacter {
log("-".repeat(100));
}
private static void moveOperatorToEXPR(Node root) {
for (Node child : root.getChildren()) {
private static void moveOperatorToEXPR(ASTNode root) {
for (ASTNode child : root.getChildren()) {
moveOperatorToEXPR(child);
}
Node op = getOp(root);
ASTNode op = getOp(root);
if (op == null || !"EXPR".equals(root.getName())) {
return;
@ -222,9 +222,9 @@ public final class ASTCompacter {
root.getChildren().remove(op);
}
private static Node getOp(Node root) {
for (Node child : root.getChildren()) {
Node op = switch (child.getName()) {
private static ASTNode getOp(ASTNode root) {
for (ASTNode child : root.getChildren()) {
ASTNode op = switch (child.getName()) {
case "ADD", "SUB", "MUL", "DIV", "MOD" -> child;
case "NOT", "AND", "OR" -> child;
case "LESS", "LESS_EQUAL", "GREATER", "GREATER_EQUAL", "EQUAL", "NOT_EQUAL" -> child;
@ -245,12 +245,12 @@ public final class ASTCompacter {
log("-".repeat(100));
}
private static void moveIdentifierToASSIGNMENT(Node root) {
for (Node child : root.getChildren()) {
private static void moveIdentifierToASSIGNMENT(ASTNode root) {
for (ASTNode child : root.getChildren()) {
moveIdentifierToASSIGNMENT(child);
}
Node id = getId(root);
ASTNode id = getId(root);
if (id == null || !"ASSIGNMENT".equals(root.getName())) {
return;
@ -261,8 +261,8 @@ public final class ASTCompacter {
root.getChildren().remove(id);
}
private static Node getId(Node root) {
for (Node child : root.getChildren()) {
private static ASTNode getId(ASTNode root) {
for (ASTNode child : root.getChildren()) {
if (child.getName().equals("IDENTIFIER")) {
return child;
}

View File

@ -6,26 +6,26 @@ import java.util.Iterator;
import java.util.List;
import java.util.Objects;
public class Node {
public class ASTNode {
private String name;
private String value;
private List<Node> children = new ArrayList<>();
private List<ASTNode> children = new ArrayList<>();
public Node(String name) {
public ASTNode(String name) {
this.name = name;
this.value = "";
}
public void addChild(Node node) {
this.children.add(node);
public void addChild(ASTNode ASTNode) {
this.children.add(ASTNode);
}
public boolean hasChildren() {
return !this.children.isEmpty();
}
public List<Node> getChildren() {
public List<ASTNode> getChildren() {
return this.children;
}
@ -54,6 +54,19 @@ public class Node {
return buffer.toString();
}
public void setChildren(List<ASTNode> children) {
this.children = children;
}
public void setChildren(ASTNode... children) {
this.children = new ArrayList<>();
this.children.addAll(Arrays.asList(children));
}
public String getValue() {
return this.value;
}
private void print(StringBuilder buffer, String prefix, String childrenPrefix) {
buffer.append(prefix);
buffer.append(this.name);
@ -63,8 +76,8 @@ public class Node {
}
buffer.append('\n');
for (Iterator<Node> it = this.children.listIterator(); it.hasNext(); ) {
Node next = it.next();
for (Iterator<ASTNode> it = this.children.listIterator(); it.hasNext(); ) {
ASTNode next = it.next();
if (it.hasNext()) {
next.print(buffer, childrenPrefix + "├── ", childrenPrefix + "");
} else {
@ -75,32 +88,19 @@ public class Node {
@Override
public boolean equals(Object obj) {
if (obj instanceof Node) {
return this.name.equals(((Node) obj).name)
&& this.value.equals(((Node) obj).value)
&& this.children.equals(((Node) obj).children);
if (obj instanceof ASTNode) {
return this.name.equals(((ASTNode) obj).name)
&& this.value.equals(((ASTNode) obj).value)
&& this.children.equals(((ASTNode) obj).children);
}
return false;
}
public String getValue() {
return this.value;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public void setChildren(Node... children) {
this.children = new ArrayList<>();
this.children.addAll(Arrays.asList(children));
}
public long size() {
int s = 0;
for (Node child : this.children) {
for (ASTNode child : this.children) {
s += child.size();
}

View File

@ -1,6 +0,0 @@
package parser.grammar;
public enum Actions {
COMPACT,
NULLABLE
}

View File

@ -9,8 +9,8 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static parser.grammar.Actions.COMPACT;
import static parser.grammar.Actions.NULLABLE;
import static parser.grammar.GrammarActions.COMPACT;
import static parser.grammar.GrammarActions.NULLABLE;
import static util.Logger.log;
public class Grammar {
@ -96,7 +96,7 @@ public class Grammar {
.collect(Collectors.toList());
// Check for action validity
List<String> enumActions = Arrays.stream(Actions.values())
List<String> enumActions = Arrays.stream(GrammarActions.values())
.map(action -> action.toString().toLowerCase())
.collect(Collectors.toList());
for (String flag : flagList) {

View File

@ -0,0 +1,8 @@
package parser.grammar;
public enum GrammarActions {
COMPACT, // Ersetzt Node mit Child, wenn es nur ein Child gibt
NULLABLE, // Entfernt Node, wenn dieser keinen Inhalt hat
MOVE, // TODO: Setzt den Child-Namen als Parent-Value und löscht das Child
RENAME // TODO: Führt eine Umbenennung durch
}

View File

@ -1,6 +1,6 @@
package parser.grammar;
import parser.LL1ParsingTable;
import parser.ParsingTable;
import java.util.AbstractMap;
import java.util.Arrays;
@ -16,16 +16,16 @@ import static util.Logger.log;
import static util.Logger.logIfTrue;
import static util.Logger.logNullable;
public class LL1GrammarAnalyzer {
public class GrammarAnalyzer {
private final Grammar grammar;
private final Map<String, Set<String>> first;
private final Map<String, Set<String>> follow;
private final LL1ParsingTable table;
private final ParsingTable table;
public LL1GrammarAnalyzer(Grammar grammar) {
public GrammarAnalyzer(Grammar grammar) {
this.grammar = grammar;
log("Analyzing Grammar:\n");
@ -214,7 +214,7 @@ public class LL1GrammarAnalyzer {
return followOut;
}
private LL1ParsingTable initParseTable() {
private ParsingTable initParseTable() {
Map<Map.Entry<String, String>, String> tableOut = new HashMap<>();
log("Parsetable Aufstellen:");
@ -265,7 +265,7 @@ public class LL1GrammarAnalyzer {
}
}
final LL1ParsingTable table = new LL1ParsingTable(this.grammar, tableOut);
final ParsingTable table = new ParsingTable(this.grammar, tableOut);
log("\n" + table);
log("-".repeat(100) + "\n");
@ -347,7 +347,7 @@ public class LL1GrammarAnalyzer {
return this.follow;
}
public LL1ParsingTable getTable() {
public ParsingTable getTable() {
return this.table;
}
}

View File

@ -1,7 +1,7 @@
package typechecker;
import parser.ast.AST;
import parser.ast.Node;
import parser.ast.ASTNode;
import java.util.HashMap;
import java.util.Map;
@ -48,14 +48,14 @@ public class SymbolTable {
return new SymbolTable(tableOut);
}
private static void scanTree(Node root, Map<String, String> table) {
for (Node child : root.getChildren()) {
private static void scanTree(ASTNode root, Map<String, String> table) {
for (ASTNode child : root.getChildren()) {
scanTree(child, table);
}
if ("DECLARATION".equals(root.getName())) {
Node left = root.getChildren().get(0);
Node right = root.getChildren().get(1);
ASTNode left = root.getChildren().get(0);
ASTNode right = root.getChildren().get(1);
log("Adding Entry " + right.getValue() + " -> " + left.getName());
String oldEntry = table.put(right.getValue(), left.getName());

View File

@ -0,0 +1,8 @@
package typechecker;
public class TypeMismatchException extends RuntimeException {
public TypeMismatchException(String message) {
super(message);
}
}

View File

@ -1,8 +0,0 @@
package typechecker;
public class WrongTypeException extends RuntimeException {
public WrongTypeException(String message) {
super(message);
}
}