add function to remove junk
This commit is contained in:
@ -2,6 +2,7 @@ package parser.ast;
|
|||||||
|
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ public final class ASTCompacter {
|
|||||||
|
|
||||||
private ASTCompacter() {}
|
private ASTCompacter() {}
|
||||||
|
|
||||||
|
// Grundreinigung
|
||||||
public static void clean(AST tree, Grammar grammar) {
|
public static void clean(AST tree, Grammar grammar) {
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
|
|
||||||
@ -18,18 +20,21 @@ public final class ASTCompacter {
|
|||||||
do {
|
do {
|
||||||
change = compact(tree, grammar)
|
change = compact(tree, grammar)
|
||||||
+ removeEpsilon(tree, grammar)
|
+ removeEpsilon(tree, grammar)
|
||||||
|
+ remove(tree)
|
||||||
+ removeNullable(tree, grammar);
|
+ removeNullable(tree, grammar);
|
||||||
|
|
||||||
removed += change;
|
removed += change;
|
||||||
} while (change != 0);
|
} while (change != 0);
|
||||||
|
|
||||||
rename(tree);
|
rename(tree);
|
||||||
|
moveOperator(tree);
|
||||||
|
|
||||||
log(tree.toString());
|
log(tree.toString());
|
||||||
log("\nCleaned Tree: " + removed + " nodes removed.");
|
log("\nCleaned Tree: " + removed + " nodes removed.");
|
||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entfernt [compact]-able Nodes (Reicht Werte nach oben)
|
||||||
public static int compact(AST tree, Grammar grammar) {
|
public static int compact(AST tree, Grammar grammar) {
|
||||||
int compacted = 0;
|
int compacted = 0;
|
||||||
|
|
||||||
@ -73,6 +78,7 @@ public final class ASTCompacter {
|
|||||||
return compacted + toRemove.size();
|
return compacted + toRemove.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entfernt [nullable] Nodes (löscht Nodes ohne Inhalt)
|
||||||
public static int removeNullable(AST tree, Grammar grammar) {
|
public static int removeNullable(AST tree, Grammar grammar) {
|
||||||
int removed = removeNullable(tree.getRoot(), grammar);
|
int removed = removeNullable(tree.getRoot(), grammar);
|
||||||
|
|
||||||
@ -106,7 +112,7 @@ public final class ASTCompacter {
|
|||||||
return removed + toRemove.size();
|
return removed + toRemove.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of removed nodes
|
// Löscht epsilon-Nodes
|
||||||
public static int removeEpsilon(AST tree, Grammar grammar) {
|
public static int removeEpsilon(AST tree, Grammar grammar) {
|
||||||
int removed = removeEpsilon(tree.getRoot(), grammar);
|
int removed = removeEpsilon(tree.getRoot(), grammar);
|
||||||
|
|
||||||
@ -136,6 +142,40 @@ public final class ASTCompacter {
|
|||||||
return removed + toRemove.size();
|
return removed + toRemove.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Löscht epsilon-Nodes
|
||||||
|
public static int remove(AST tree) {
|
||||||
|
int removed = remove(tree.getRoot());
|
||||||
|
|
||||||
|
if (removed != 0) {
|
||||||
|
log("Removed " + removed + " nodes.");
|
||||||
|
log("-".repeat(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int remove(Node root) {
|
||||||
|
int removed = 0;
|
||||||
|
Collection<Node> toRemove = new HashSet<>();
|
||||||
|
|
||||||
|
Collection<String> removable = Arrays.asList("IF", "ELSE", "WHILE");
|
||||||
|
|
||||||
|
for (Node child : root.getChildren()) {
|
||||||
|
if (removable.contains(child.getName()) && !child.hasChildren()) {
|
||||||
|
log("Removing " + root.getName() + " -> " + child.getName());
|
||||||
|
toRemove.add(child);
|
||||||
|
} else {
|
||||||
|
removed += remove(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.getChildren().removeAll(toRemove);
|
||||||
|
|
||||||
|
return removed + toRemove.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Umbenennungen
|
||||||
|
// EXPR_2 -> EXPR, EXPR_F -> EXPR
|
||||||
private static void rename(AST tree) {
|
private static void rename(AST tree) {
|
||||||
rename(tree.getRoot());
|
rename(tree.getRoot());
|
||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
@ -157,4 +197,43 @@ public final class ASTCompacter {
|
|||||||
rename(child);
|
rename(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EXPR bekommt die Operation als Value anstatt als Child
|
||||||
|
public static void moveOperator(AST tree) {
|
||||||
|
moveOperator(tree.getRoot());
|
||||||
|
log("-".repeat(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void moveOperator(Node root) {
|
||||||
|
for (Node child : root.getChildren()) {
|
||||||
|
moveOperator(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node op = getOp(root);
|
||||||
|
|
||||||
|
if (op == null || !"EXPR".equals(root.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("Moving operator " + op.getName() + " to " + root.getName());
|
||||||
|
root.setValue(op.getName());
|
||||||
|
root.getChildren().remove(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Node getOp(Node root) {
|
||||||
|
for (Node child : root.getChildren()) {
|
||||||
|
Node 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;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (op != null) {
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user