overhaul logging + printing ast to image
This commit is contained in:
@ -45,7 +45,7 @@ public final class StupsCompiler {
|
||||
final FlowGraphGenerator gen = getFlowGraphGen(filename);
|
||||
final FlowGraph graph = gen.generateGraph();
|
||||
|
||||
Logger.logInfoSupplier(graph::printToImage, StupsCompiler.class);
|
||||
Logger.logDebugSupplier(graph::printToImage, StupsCompiler.class);
|
||||
|
||||
// Codegeneration + Output
|
||||
final String fileExtension = filename.substring(filename.lastIndexOf('.') + 1);
|
||||
@ -79,11 +79,11 @@ public final class StupsCompiler {
|
||||
final FlowGraphGenerator gen = getFlowGraphGen(filename);
|
||||
final FlowGraph graph = gen.generateGraph();
|
||||
|
||||
Logger.logInfoSupplier(graph::printToImage, StupsCompiler.class);
|
||||
Logger.logDebugSupplier(graph::printToImage, StupsCompiler.class);
|
||||
|
||||
final DataFlowGraph dataFlowGraph = DataFlowGraph.fromFlowGraph(graph);
|
||||
|
||||
Logger.logInfoSupplier(dataFlowGraph::printToImage, StupsCompiler.class);
|
||||
Logger.logDebugSupplier(dataFlowGraph::printToImage, StupsCompiler.class);
|
||||
|
||||
final LivenessAnalysis liveness = LivenessAnalysis.fromDataFlowGraph(dataFlowGraph, gen.getVarMap());
|
||||
final int registers = liveness.doLivenessAnalysis();
|
||||
@ -129,7 +129,10 @@ public final class StupsCompiler {
|
||||
// Parsing + Typechecking of program
|
||||
final SyntaxTree parseTree = stupsParser.parse(lexer.getAllTokens(), lexer.getVocabulary());
|
||||
|
||||
Logger.logDebugSupplier(() -> parseTree.printToImage("ParseTree"), StupsCompiler.class);
|
||||
|
||||
final SyntaxTree abstractSyntaxTree = SyntaxTree.toAbstractSyntaxTree(parseTree, grammar);
|
||||
|
||||
final Map<SyntaxTreeNode, String> nodeTable = TypeChecker.validate(abstractSyntaxTree);
|
||||
|
||||
return FlowGraphGenerator.fromAST(abstractSyntaxTree, nodeTable, filename);
|
||||
|
@ -98,7 +98,7 @@ public final class DataFlowGraph implements Iterable<DataFlowNode> {
|
||||
|
||||
public String printToImage() {
|
||||
if (this.dataFlowNodes.isEmpty()) {
|
||||
return "Empty Graph";
|
||||
return "Can't export empty graph: DataFLowGraph.svg";
|
||||
}
|
||||
|
||||
final StringBuilder dot = new StringBuilder();
|
||||
@ -132,7 +132,7 @@ public final class DataFlowGraph implements Iterable<DataFlowNode> {
|
||||
|
||||
GraphvizCaller.callGraphviz(dot, "DataFlowGraph");
|
||||
|
||||
return "Finished.";
|
||||
return "Successfully exported as image: DataFlowGraph.svg";
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
@ -69,7 +69,7 @@ public final class InterferenceGraph implements Iterable<InterferenceNode> {
|
||||
|
||||
public String printToImage() {
|
||||
if (this.interferenceNodes.isEmpty()) {
|
||||
return "Empty Graph";
|
||||
return "Can't export empty graph: Interference.svg";
|
||||
}
|
||||
|
||||
final StringBuilder dot = new StringBuilder();
|
||||
@ -100,7 +100,7 @@ public final class InterferenceGraph implements Iterable<InterferenceNode> {
|
||||
|
||||
GraphvizCaller.callGraphviz(dot, "InterferenceGraph");
|
||||
|
||||
return "Finished.";
|
||||
return "Successfully exported as Image: InterferenceGraph.svg";
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
@ -107,7 +107,7 @@ public final class LivenessAnalysis {
|
||||
Logger.logDebug("Successfully colored interference-graph", LivenessAnalysis.class);
|
||||
}
|
||||
|
||||
Logger.logInfoSupplier(this.interferenceGraph::printToImage, LivenessAnalysis.class);
|
||||
Logger.logDebugSupplier(this.interferenceGraph::printToImage, LivenessAnalysis.class);
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
@ -48,13 +48,16 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
* und zu Blöcken aus der {@link #predecessorMap} hergestellt.
|
||||
*/
|
||||
public void addLabel(String label) {
|
||||
Logger.logInfo("Adding Label: " + label, FlowGraph.class);
|
||||
Logger.logInfo(" :: Adding label: \"" + label + "\"", FlowGraph.class);
|
||||
|
||||
final FlowBasicBlock newBlock = new FlowBasicBlock(label);
|
||||
|
||||
// Resolve missing successors/predecessors from jumps
|
||||
if (this.predecessorMap.containsKey(label)) {
|
||||
Logger.logInfo("Handling PredecessorMap Entry: " + this.predecessorMap.get(label), FlowGraph.class);
|
||||
Logger.logInfo(" :: Handling predecessor-map entry:\n\t\t\t"
|
||||
+ this.predecessorMap.get(label).getLabel()
|
||||
+ "\n\t\t\t[...]\n\t\t\t"
|
||||
+ this.predecessorMap.get(label).getLastInstruction(), FlowGraph.class);
|
||||
|
||||
this.predecessorMap.get(label).addSuccessorBlock(newBlock);
|
||||
newBlock.addPredecessorBlock(this.predecessorMap.get(label));
|
||||
@ -79,7 +82,7 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
* @param jumpInstruction Der verwendete Sprungbefehl.
|
||||
*/
|
||||
public void addJump(String jumpInstruction, String label) {
|
||||
Logger.logInfo("Adding Jump to Label: " + label, FlowGraph.class);
|
||||
Logger.logInfo(" :: Adding jump to label \"" + label + "\"", FlowGraph.class);
|
||||
|
||||
this.addInstruction(jumpInstruction, label);
|
||||
|
||||
@ -111,7 +114,9 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
// Successor doesn't exist, so wait until it does
|
||||
|
||||
// Current node is predecessor of label-block
|
||||
Logger.logInfo("Adding Entry to PredecessorMap: " + currentBlock, FlowGraph.class);
|
||||
currentBlock.ifPresent(flowBasicBlock -> Logger.logInfo(" :: Adding entry to predecessor-map: \n\t\t\t"
|
||||
+ flowBasicBlock.getLabel() + "\n\t\t\t[...]\n\t\t\t"
|
||||
+ flowBasicBlock.getLastInstruction(), FlowGraph.class));
|
||||
currentBlock.ifPresent(flowBasicBlock -> this.predecessorMap.put(label, flowBasicBlock));
|
||||
}
|
||||
|
||||
@ -119,7 +124,7 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
}
|
||||
|
||||
public void addInstruction(String instruction, String... args) {
|
||||
Logger.logInfo("Adding Instruction: " + instruction, FlowGraph.class);
|
||||
Logger.logInfo(" :: Adding instruction \"" + instruction + "\"", FlowGraph.class);
|
||||
|
||||
if (this.basicBlocks.isEmpty()) {
|
||||
this.basicBlocks.add(new FlowBasicBlock("START")); // First block doesn't exist
|
||||
@ -143,7 +148,7 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
// Collect removable blocks
|
||||
for (FlowBasicBlock block : this.basicBlocks) {
|
||||
if (block.isEmpty()) {
|
||||
Logger.logInfo("Marking Block " + this.basicBlocks.indexOf(block) + " as removable.", FlowGraph.class);
|
||||
Logger.logInfo(" :: Marking block nr. " + this.basicBlocks.indexOf(block) + " as removable.", FlowGraph.class);
|
||||
toRemove.add(block);
|
||||
}
|
||||
}
|
||||
@ -155,8 +160,8 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
for (FlowBasicBlock predecessor : block.getBlockPredecessorSet()) {
|
||||
for (FlowBasicBlock successor : block.getBlockSuccessorSet()) {
|
||||
|
||||
Logger.logInfo("Rerouting Block " + this.basicBlocks.indexOf(predecessor)
|
||||
+ " to Block " + this.basicBlocks.indexOf(successor), FlowGraph.class);
|
||||
Logger.logInfo(" :: Rerouting block nr. " + this.basicBlocks.indexOf(predecessor)
|
||||
+ " to block nr. " + this.basicBlocks.indexOf(successor), FlowGraph.class);
|
||||
predecessor.addSuccessorBlock(successor);
|
||||
successor.addPredecessorBlock(predecessor);
|
||||
}
|
||||
@ -200,7 +205,7 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
final Optional<FlowBasicBlock> currentBlock = this.getCurrentBlock();
|
||||
|
||||
if (this.basicBlocks.isEmpty() || currentBlock.isEmpty()) {
|
||||
return "Empty Graph";
|
||||
return "Can't export empty graph: FlowGraph.svg";
|
||||
}
|
||||
|
||||
final StringBuilder dot = new StringBuilder();
|
||||
@ -237,7 +242,7 @@ public class FlowGraph implements Iterable<FlowBasicBlock> {
|
||||
|
||||
GraphvizCaller.callGraphviz(dot, "FlowGraph");
|
||||
|
||||
return "Finished.";
|
||||
return "Successfully exported the graph as Image: FlowGraph.svg";
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
@ -75,9 +75,8 @@ public final class FlowGraphGenerator {
|
||||
|
||||
currentVarNumber++;
|
||||
varMap.put(current.getChildren().get(0).getValue(), currentVarNumber);
|
||||
Logger.logInfo("New local " + current.getValue() + " variable "
|
||||
+ current.getChildren().get(0).getValue()
|
||||
+ " assigned to slot " + currentVarNumber + ".", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Assign local variable \"" + current.getChildren().get(0).getValue() + "\" -> \""
|
||||
+ current.getValue() + "\" to slot " + currentVarNumber, FlowGraphGenerator.class);
|
||||
}
|
||||
|
||||
current.getChildren().forEach(stack::push);
|
||||
@ -110,7 +109,6 @@ public final class FlowGraphGenerator {
|
||||
this.graph.purgeEmptyBlocks();
|
||||
|
||||
Logger.logDebug("Source-graph generation complete", FlowGraphGenerator.class);
|
||||
Logger.logInfo("\n\nSourceGraph print:\n" + "-".repeat(100) + "\n" + this.graph + "-".repeat(100), FlowGraphGenerator.class);
|
||||
|
||||
return this.graph;
|
||||
}
|
||||
@ -138,7 +136,7 @@ public final class FlowGraphGenerator {
|
||||
* Erzeugt den Teilbaum für einen If-Knoten.
|
||||
*/
|
||||
private void condNode(SyntaxTreeNode root) {
|
||||
Logger.logInfo("Generating Conditional Node", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Generating conditional node", FlowGraphGenerator.class);
|
||||
|
||||
final int currentLabel = this.labelCounter;
|
||||
this.labelCounter++;
|
||||
@ -169,7 +167,7 @@ public final class FlowGraphGenerator {
|
||||
* Erzeugt den Teilbaum für einen While-Knoten.
|
||||
*/
|
||||
private void loopNode(SyntaxTreeNode root) {
|
||||
Logger.logInfo("Generating Loop Node", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Generating loop node", FlowGraphGenerator.class);
|
||||
|
||||
final int currentLabel = this.labelCounter;
|
||||
this.labelCounter++;
|
||||
@ -196,7 +194,7 @@ public final class FlowGraphGenerator {
|
||||
* Die JVM-Stacksize wird dabei um 1 verringert, da istore/astore 1 Argument konsumieren.
|
||||
*/
|
||||
private void assignNode(SyntaxTreeNode root) { //! Stack - 1
|
||||
Logger.logInfo("Generating Assignment Node", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Generating assignment node", FlowGraphGenerator.class);
|
||||
|
||||
this.generateNode(root.getChildren().get(0));
|
||||
|
||||
@ -207,7 +205,7 @@ public final class FlowGraphGenerator {
|
||||
default -> throw new IllegalStateException("Unexpected value: " + type);
|
||||
};
|
||||
|
||||
Logger.logInfo("assign(): " + root.getName() + ": " + root.getValue() + " => " + inst, FlowGraphGenerator.class);
|
||||
Logger.logInfo("assign(): Node \"" + root.getName() + ": " + root.getValue() + "\" => " + inst, FlowGraphGenerator.class);
|
||||
|
||||
this.graph.addInstruction(inst, this.varMap.get(root.getValue()).toString());
|
||||
}
|
||||
@ -229,7 +227,7 @@ public final class FlowGraphGenerator {
|
||||
* bei binären Operatoren sinkt die Stackgröße um 1 (2 konsumiert, 1 Ergebnis).
|
||||
*/
|
||||
private void intExpr(SyntaxTreeNode root) {
|
||||
Logger.logInfo("Generating Integer Expression Node", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Generating integer expression node: \"" + root.getName() + ": " + root.getValue() + "\"", FlowGraphGenerator.class);
|
||||
|
||||
String inst = "";
|
||||
|
||||
@ -259,7 +257,7 @@ public final class FlowGraphGenerator {
|
||||
};
|
||||
}
|
||||
|
||||
Logger.logInfo("intExpr(): " + root.getName() + ": " + root.getValue() + " => " + inst, FlowGraphGenerator.class);
|
||||
Logger.logInfo("intExpr(): Node \"" + root.getName() + ": " + root.getValue() + "\" => " + inst, FlowGraphGenerator.class);
|
||||
|
||||
this.graph.addInstruction(inst);
|
||||
}
|
||||
@ -270,7 +268,7 @@ public final class FlowGraphGenerator {
|
||||
* bei binären Operatoren sinkt die Stackgröße um 1 (2 konsumiert, 1 Ergebnis).
|
||||
*/
|
||||
private void boolExpr(SyntaxTreeNode node) {
|
||||
Logger.logInfo("Generating Boolean Expression", FlowGraphGenerator.class);
|
||||
Logger.logInfo("Generating boolean expression", FlowGraphGenerator.class);
|
||||
|
||||
if (node.getChildren().size() == 1) { //! Stack + 1
|
||||
// Unary operator
|
||||
@ -342,14 +340,14 @@ public final class FlowGraphGenerator {
|
||||
// Leafs
|
||||
|
||||
private void intStringLiteralNode(SyntaxTreeNode node) { //! Stack + 1
|
||||
Logger.logInfo("intStringLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc", FlowGraphGenerator.class);
|
||||
Logger.logInfo("intStringLiteral(): Node \"" + node.getName() + ": " + node.getValue() + "\" => ldc", FlowGraphGenerator.class);
|
||||
|
||||
// bipush only pushes 1 byte as int
|
||||
this.graph.addInstruction("ldc", node.getValue());
|
||||
}
|
||||
|
||||
private void boolLiteralNode(SyntaxTreeNode node) { //! Stack + 1
|
||||
Logger.logInfo("booleanLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc", FlowGraphGenerator.class);
|
||||
Logger.logInfo("booleanLiteral(): Node \"" + node.getName() + ": " + node.getValue() + "\" => ldc", FlowGraphGenerator.class);
|
||||
|
||||
final String val = "true".equals(node.getValue()) ? "1" : "0";
|
||||
|
||||
@ -364,7 +362,7 @@ public final class FlowGraphGenerator {
|
||||
default -> throw new IllegalStateException("Unexpected value: " + type);
|
||||
};
|
||||
|
||||
Logger.logInfo("identifier(): " + node.getName() + ": " + node.getValue() + " => " + inst, FlowGraphGenerator.class);
|
||||
Logger.logInfo("identifier(): Node \"" + node.getName() + ": " + node.getValue() + "\" => " + inst, FlowGraphGenerator.class);
|
||||
|
||||
this.graph.addInstruction(inst, this.varMap.get(node.getValue()).toString());
|
||||
}
|
||||
@ -382,7 +380,7 @@ public final class FlowGraphGenerator {
|
||||
|
||||
this.generateNode(expr);
|
||||
|
||||
Logger.logInfo("println(): " + expr.getName() + ": " + expr.getValue() + " => " + type, FlowGraphGenerator.class);
|
||||
Logger.logInfo("println(): Node \"" + expr.getName() + ": " + expr.getValue() + "\" => " + type, FlowGraphGenerator.class);
|
||||
|
||||
this.graph.addInstruction("invokevirtual", "java/io/PrintStream/println(" + type + ")V");
|
||||
}
|
||||
|
@ -49,13 +49,11 @@ public class StupsParser {
|
||||
|
||||
int inputPosition = 0;
|
||||
|
||||
Logger.logInfo("Input: " + token + "\n", StupsParser.class);
|
||||
|
||||
// Parsing
|
||||
while (!stack.isEmpty()) {
|
||||
final String top = stack.peek().getName();
|
||||
|
||||
Logger.logInfo("Parsing Top Symbol: " + top, StupsParser.class);
|
||||
Logger.logInfo("Parsing Top Symbol: \"" + top + "\"", StupsParser.class);
|
||||
|
||||
final String currentTokenSym;
|
||||
int currentLine = 0;
|
||||
@ -76,16 +74,20 @@ public class StupsParser {
|
||||
if (top.equals(Grammar.EPSILON_SYMBOL)) {
|
||||
// Wenn auf dem Stack das Epsilonsymbol liegt
|
||||
|
||||
// Logger.logInfo(" :: Skip epsilon", StupsParser.class);
|
||||
|
||||
stack.pop();
|
||||
} else if (top.equals(currentTokenSym)) {
|
||||
// Wenn auf dem Stack ein Terminal liegt (dieses muss mit der Eingabe übereinstimmen)
|
||||
|
||||
// Logger.logInfo(" :: Skip terminal-symbol (Matches input)", StupsParser.class);
|
||||
|
||||
stack.pop();
|
||||
inputPosition++;
|
||||
} else if (this.parsetable.getTerminals().contains(top)) {
|
||||
// Wenn das Terminal auf dem Stack nicht mit der aktuellen Eingabe übereinstimmt
|
||||
|
||||
Logger.logError("\nLine " + currentLine + " Syntaxerror: Expected " + top + " but found "
|
||||
Logger.logError("Line " + currentLine + " Syntaxerror: Expected " + top + " but found "
|
||||
+ currentTokenSym, StupsParser.class);
|
||||
Logger.logError(StupsParser.printSourceLine(currentLine, token), StupsParser.class);
|
||||
|
||||
@ -93,7 +95,7 @@ public class StupsParser {
|
||||
} else if (prod == null) {
|
||||
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
|
||||
|
||||
Logger.logError("\nLine " + currentLine + " Syntaxerror: Didn't expect " + currentTokenSym, StupsParser.class);
|
||||
Logger.logError("Line " + currentLine + " Syntaxerror: Didn't expect " + currentTokenSym, StupsParser.class);
|
||||
Logger.logError(StupsParser.printSourceLine(currentLine, token), StupsParser.class);
|
||||
|
||||
throw new ParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
|
||||
@ -101,7 +103,7 @@ public class StupsParser {
|
||||
// Wenn das Nichtterminal auf dem Stack durch (s)eine Produktion ersetzt werden kann
|
||||
// Hier wird auch der AST aufgebaut
|
||||
|
||||
Logger.logInfo("Used: " + top + " -> " + prod, StupsParser.class);
|
||||
Logger.logInfo(" :: Used rule: \"" + top + " -> " + prod + "\"", StupsParser.class);
|
||||
final SyntaxTreeNode pop = stack.pop();
|
||||
|
||||
final String[] split = prod.split(" ");
|
||||
@ -126,7 +128,6 @@ public class StupsParser {
|
||||
}
|
||||
|
||||
Logger.logDebug("Successfully parsed the program and built the parse-tree", StupsParser.class);
|
||||
Logger.logInfo("\nParsed AST:\n" + tree, StupsParser.class);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public final class ParseTreeCleaner {
|
||||
valueToValue(parseTree, grammar);
|
||||
|
||||
Logger.logDebug("Successfully cleaned the parse-tree", ParseTreeCleaner.class);
|
||||
Logger.logInfo("\nCleaned Tree:\n" + parseTree, ParseTreeCleaner.class);
|
||||
Logger.logDebugSupplier(() -> parseTree.printToImage("ParseTreeCleaned"), ParseTreeCleaner.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,8 +57,8 @@ public final class ParseTreeCleaner {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.logInfo("Promoting " + child.getName() + " -> " + root.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo(root.toString(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Promoting child \"" + child.getName() + "\" to root \"" + root.getName() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), ParseTreeCleaner.class);
|
||||
|
||||
root.setName(child.getName());
|
||||
root.setValue(child.getValue());
|
||||
@ -90,7 +90,7 @@ public final class ParseTreeCleaner {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.logInfo("Removing " + child.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Removing node \"" + child.getName() + "\"", ParseTreeCleaner.class);
|
||||
|
||||
child.setValue("REMOVE"); // If both childs have the same identity both are removed, so change one
|
||||
toRemove.add(child);
|
||||
@ -118,7 +118,8 @@ public final class ParseTreeCleaner {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.logInfo("Removing " + root.getName() + " -> " + child.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Removing child \"" + child.getName() + "\" from root \"" + root.getName() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), ParseTreeCleaner.class);
|
||||
|
||||
child.setValue("REMOVE"); // If both childs have the same identity both are removed, so change one
|
||||
toRemove.add(child);
|
||||
@ -144,7 +145,7 @@ public final class ParseTreeCleaner {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.logInfo("Rename " + root.getName() + " to " + grammar.getNewName(root) + ".", ParseTreeCleaner.class);
|
||||
Logger.logInfo("Renaming node \"" + root.getName() + "\" to \"" + grammar.getNewName(root) + "\"", ParseTreeCleaner.class);
|
||||
|
||||
root.setName(grammar.getNewName(root));
|
||||
}
|
||||
@ -169,8 +170,8 @@ public final class ParseTreeCleaner {
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.logInfo("Moving " + child.getName() + " to value of " + root.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo(root.toString(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Moving child-name \"" + child.getName() + "\" to parent-value of node \"" + root.getName() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), ParseTreeCleaner.class);
|
||||
|
||||
root.setValue(child.getName());
|
||||
|
||||
@ -206,8 +207,9 @@ public final class ParseTreeCleaner {
|
||||
&& root.getChildren().get(0).getName().equals(root.getChildren().get(1).getName())) {
|
||||
// Case where variable is assigned another variable with the same name
|
||||
|
||||
Logger.logInfo("Moving " + root.getChildren().get(1).getValue() + " to value of " + root.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo(root.toString(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Moving child-value \"" + root.getChildren().get(1).getValue()
|
||||
+ "\" to parent-value of node \"" + root.getName() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), ParseTreeCleaner.class);
|
||||
|
||||
root.setValue(root.getChildren().get(1).getValue());
|
||||
|
||||
@ -217,8 +219,8 @@ public final class ParseTreeCleaner {
|
||||
} else {
|
||||
// Usual case where an expression is assigned
|
||||
|
||||
Logger.logInfo("Moving " + child.getValue() + " to value of " + root.getName(), ParseTreeCleaner.class);
|
||||
Logger.logInfo(root.toString(), ParseTreeCleaner.class);
|
||||
Logger.logInfo("Moving child value \"" + child.getValue() + "\" to parent-value of node \""
|
||||
+ root.getName() + "\"\n" + root.nodePrint("\t\t"), ParseTreeCleaner.class);
|
||||
|
||||
root.setValue(child.getValue());
|
||||
toRemove.add(child);
|
||||
|
@ -1,7 +1,10 @@
|
||||
package parser.ast;
|
||||
|
||||
import parser.grammar.Grammar;
|
||||
import util.GraphvizCaller;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -47,6 +50,52 @@ public class SyntaxTree {
|
||||
return this.root.isEmpty();
|
||||
}
|
||||
|
||||
public String printToImage(String filename) {
|
||||
if (this.isEmpty()) {
|
||||
return "Empty tree can't be exported to image: " + filename + ".svg";
|
||||
}
|
||||
|
||||
final Deque<SyntaxTreeNode> stack = new ArrayDeque<>();
|
||||
final StringBuilder dot = new StringBuilder();
|
||||
|
||||
dot.append("digraph tree {\n")
|
||||
.append("node[shape=Mrecord]\n");
|
||||
|
||||
stack.push(this.root);
|
||||
while (!stack.isEmpty()) {
|
||||
final SyntaxTreeNode current = stack.pop();
|
||||
|
||||
dot.append("\"").append(current.getId()).append("\"")
|
||||
.append(" [label=\"{<f0> ")
|
||||
.append(current.getName())
|
||||
.append("|<f1> ")
|
||||
.append(current.getValue())
|
||||
.append("}\"];\n");
|
||||
|
||||
current.getChildren().forEach(stack::push);
|
||||
}
|
||||
|
||||
stack.push(this.root);
|
||||
while (!stack.isEmpty()) {
|
||||
final SyntaxTreeNode current = stack.pop();
|
||||
|
||||
for (SyntaxTreeNode child : current.getChildren()) {
|
||||
dot.append("\"").append(current.getId()).append("\"")
|
||||
.append(" -> ")
|
||||
.append("\"").append(child.getId()).append("\"")
|
||||
.append("\n");
|
||||
}
|
||||
|
||||
current.getChildren().forEach(stack::push);
|
||||
}
|
||||
|
||||
dot.append("}");
|
||||
|
||||
GraphvizCaller.callGraphviz(dot, filename);
|
||||
|
||||
return "Successfully generated image of syntax-tree: " + filename + ".svg";
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -13,12 +14,14 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class SyntaxTreeNode {
|
||||
|
||||
private final UUID id;
|
||||
private final int line;
|
||||
private String name;
|
||||
private String value;
|
||||
private List<SyntaxTreeNode> children = new ArrayList<>();
|
||||
|
||||
public SyntaxTreeNode(String name, int line) {
|
||||
this.id = UUID.randomUUID();
|
||||
this.name = name;
|
||||
this.line = line;
|
||||
this.value = "";
|
||||
@ -82,6 +85,10 @@ public class SyntaxTreeNode {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
// Printing
|
||||
|
||||
// toString() und treePrint() von hier: https://stackoverflow.com/a/8948691
|
||||
@ -104,6 +111,13 @@ public class SyntaxTreeNode {
|
||||
}
|
||||
}
|
||||
|
||||
public String nodePrint(String prefix) {
|
||||
return prefix + this.name + ": " + this.value + "\n"
|
||||
+ prefix + this.children.stream()
|
||||
.map(child -> prefix + "└── " + child.name + ": " + child.value + "\n")
|
||||
.collect(Collectors.joining()).trim();
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
||||
@Override
|
||||
|
@ -70,7 +70,7 @@ public final class SyntaxTreeRebalancer {
|
||||
flipCommutativeExpr(abstractSyntaxTree);
|
||||
|
||||
Logger.logDebug("Successfully rebalanced syntax-tree", SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo("AST after rebalancing:" + abstractSyntaxTree, SyntaxTreeRebalancer.class);
|
||||
Logger.logDebugSupplier(() -> abstractSyntaxTree.printToImage("AbstractSyntaxTree"), SyntaxTreeRebalancer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,8 +110,8 @@ public final class SyntaxTreeRebalancer {
|
||||
if (root.getChildren().size() == 2 && root.getChildren().get(0).size() < root.getChildren().get(1).size()) {
|
||||
// Make the bigger subtree the left one
|
||||
|
||||
Logger.logInfo("Flipping " + root.getName() + ": " + root.getValue() + " for stack efficiency.", SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo(root.toString(), SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo("Flipping node \"" + root.getName() + ": " + root.getValue() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), SyntaxTreeRebalancer.class);
|
||||
|
||||
Collections.reverse(root.getChildren());
|
||||
}
|
||||
@ -153,8 +153,8 @@ public final class SyntaxTreeRebalancer {
|
||||
* @return Es wird false zurückgegeben, sobald keine weitere Rotation mehr möglich ist.
|
||||
*/
|
||||
private static boolean specialLeftRotate(SyntaxTreeNode root) {
|
||||
Logger.logInfo("Special-Left-Rotation around " + root.getName(), SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo(root.toString(), SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo("Special-left-rotation around node \"" + root.getName() + ": " + root.getValue() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), SyntaxTreeRebalancer.class);
|
||||
|
||||
final SyntaxTreeNode left = root.getChildren().get(0);
|
||||
final SyntaxTreeNode right = root.getChildren().get(1);
|
||||
@ -245,8 +245,8 @@ public final class SyntaxTreeRebalancer {
|
||||
}
|
||||
|
||||
private static void simpleRightRotate(SyntaxTreeNode root) {
|
||||
Logger.logInfo("Right-Rotation around " + root.getName() + ": " + root.getValue(), SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo(root.toString(), SyntaxTreeRebalancer.class);
|
||||
Logger.logInfo("Simple right-rotation around node \"" + root.getName() + ": " + root.getValue() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), SyntaxTreeRebalancer.class);
|
||||
|
||||
final SyntaxTreeNode left = root.getChildren().get(0);
|
||||
final SyntaxTreeNode right = root.getChildren().get(1);
|
||||
|
@ -118,15 +118,23 @@ public class Grammar {
|
||||
Logger.logDebug("Beginning grammar parsing", Grammar.class);
|
||||
for (String currentLine : lines) {
|
||||
|
||||
Logger.logInfo("Parsed: " + currentLine, Grammar.class);
|
||||
Logger.logInfo("Parsing: \"" + currentLine + "\"", Grammar.class);
|
||||
|
||||
// Parse Keywords
|
||||
if (currentLine.startsWith("TERM:")) {
|
||||
|
||||
terminals.addAll(Arrays.stream(currentLine.split(" ")).skip(1).collect(Collectors.toSet()));
|
||||
|
||||
Arrays.stream(currentLine.split(" "))
|
||||
.skip(1)
|
||||
.forEach(term -> Logger.logInfo(" :: Registered terminal symbol \"" + term + "\"", Grammar.class));
|
||||
} else if (currentLine.startsWith("NTERM:")) {
|
||||
|
||||
nonterminals.addAll(Arrays.stream(currentLine.split(" ")).skip(1).collect(Collectors.toSet()));
|
||||
|
||||
Arrays.stream(currentLine.split(" "))
|
||||
.skip(1)
|
||||
.forEach(nterm -> Logger.logInfo(" :: Registered nonterminal symbol \"" + nterm + "\"", Grammar.class));
|
||||
} else {
|
||||
// Parse regular lines
|
||||
|
||||
@ -136,7 +144,10 @@ public class Grammar {
|
||||
}
|
||||
}
|
||||
|
||||
Logger.logInfo("Registered actions: " + actionMap, Grammar.class);
|
||||
Logger.logInfo("Grammar terminals: " + terminals, Grammar.class);
|
||||
Logger.logInfo("Grammar nonterminals: " + nonterminals, Grammar.class);
|
||||
Logger.logInfo("Grammar productions: " + rules, Grammar.class);
|
||||
Logger.logInfo("Grammar actions: " + actionMap, Grammar.class);
|
||||
Logger.logDebug("Grammar parsed successfully", Grammar.class);
|
||||
|
||||
return new Grammar(terminals, nonterminals,
|
||||
@ -170,8 +181,6 @@ public class Grammar {
|
||||
|
||||
final Set<String> actionSet = parseActionSet(leftside, open, close);
|
||||
|
||||
Logger.logInfo("Current Line " + currentLine + " has Actions: " + actionSet, Grammar.class);
|
||||
|
||||
// Validate Actions
|
||||
throwOnInvalidActionSet(actionSet);
|
||||
|
||||
@ -230,7 +239,7 @@ public class Grammar {
|
||||
Map<GrammarAction, Set<String>> actions) {
|
||||
|
||||
actions.get(action).add(leftside.trim());
|
||||
Logger.logInfo("Registered " + flag + ": " + leftside.trim(), Grammar.class);
|
||||
Logger.logInfo(" :: Registered action [" + flag + "] for \"" + leftside.trim() + "\"", Grammar.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,7 +255,8 @@ public class Grammar {
|
||||
final int argStart = flag.indexOf('=');
|
||||
final String[] argSplit = flag.substring(argStart + 1).split(",");
|
||||
|
||||
Logger.logInfo("Registered " + flag + " args: " + argSplit, Grammar.class);
|
||||
Arrays.stream(argSplit)
|
||||
.forEach(arg -> Logger.logInfo(" :: Action has arg " + arg, Grammar.class));
|
||||
|
||||
switch (action) {
|
||||
case DELCHILD -> delChildMappings.put(leftside, Arrays.asList(argSplit));
|
||||
@ -270,7 +280,7 @@ public class Grammar {
|
||||
final GrammarRule rule = new GrammarRule(leftside, prod.split(" "));
|
||||
rules.add(rule);
|
||||
|
||||
Logger.logInfo("Registered production " + rule, Grammar.class);
|
||||
Logger.logInfo(" :: Registered production \"" + rule + "\"", Grammar.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ public final class GrammarAnalyzer {
|
||||
for (String rightside : this.grammar.getRightsides(leftside)) {
|
||||
// ...and X -> Y1 Y2 ... Yk is a production...
|
||||
|
||||
|
||||
if (!rightside.equals(Grammar.EPSILON_SYMBOL)) {
|
||||
// ...for some k >= 1...
|
||||
|
||||
@ -107,8 +108,9 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = firstOut.get(leftside).addAll(firstYiNoEps);
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "First: Added " + firstYiNoEps + " to "
|
||||
+ leftside + " (All before are nullable)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added " + firstYiNoEps + " to \"first("
|
||||
+ leftside + ")\" (All before are nullable)", GrammarAnalyzer.class);
|
||||
}
|
||||
|
||||
if (i == split.length - 1 && allNullable.test(split)) {
|
||||
@ -117,8 +119,9 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = firstOut.get(leftside).add(Grammar.EPSILON_SYMBOL);
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "First: Added " + Grammar.EPSILON_SYMBOL + " to "
|
||||
+ leftside + " (All are nullable)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added [" + Grammar.EPSILON_SYMBOL + "] to \"first("
|
||||
+ leftside + ")\" (All are nullable)", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,15 +132,16 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = firstOut.get(leftside).add(Grammar.EPSILON_SYMBOL);
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "First: Added " + Grammar.EPSILON_SYMBOL + " to "
|
||||
+ leftside + " (X -> EPS exists)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added [" + Grammar.EPSILON_SYMBOL + "] to \"first("
|
||||
+ leftside + ")\" (X -> EPS exists)", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (change);
|
||||
|
||||
Logger.logDebug(" :: First-set initialized successfully", GrammarAnalyzer.class);
|
||||
Logger.logInfo("First Set: " + firstOut, GrammarAnalyzer.class);
|
||||
Logger.logDebug(" :: First-set initialized successfully", GrammarAnalyzer.class);
|
||||
|
||||
return firstOut;
|
||||
}
|
||||
@ -192,8 +196,9 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = followOut.get(split[i - 1]).addAll(firstXkNoEps);
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "Follow: Added " + firstXkNoEps + " to "
|
||||
+ split[i - 1] + " (Dazwischen nullable)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added " + firstXkNoEps + " to \"follow("
|
||||
+ split[i - 1] + ")\" (All nullable inbetween)", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,8 +211,9 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = followOut.get(split[i - 1]).addAll(followOut.get(leftside));
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "Follow: Added " + leftside + " to "
|
||||
+ split[i - 1] + " (Dahinter nullable)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added " + leftside + " to \"follow("
|
||||
+ split[i - 1] + ")\" (All following are nullable)", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,16 +223,17 @@ public final class GrammarAnalyzer {
|
||||
final boolean changeNow = followOut.get(split[split.length - 1]).addAll(followOut.get(leftside));
|
||||
change = change || changeNow;
|
||||
|
||||
Logger.logInfoIfTrue(changeNow, "Follow: Added " + followOut.get(leftside) + " to "
|
||||
+ split[split.length - 1] + " (Ende der Regel)", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, "Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfoIfTrue(changeNow, " :: Added " + followOut.get(leftside) + " to \"follow("
|
||||
+ split[split.length - 1] + ")\" (Last item in production)", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (change);
|
||||
|
||||
Logger.logDebug(" :: Follow-set initialized successfully", GrammarAnalyzer.class);
|
||||
Logger.logInfo("Follow Set: " + followOut, GrammarAnalyzer.class);
|
||||
Logger.logDebug(" :: Follow-set initialized successfully", GrammarAnalyzer.class);
|
||||
|
||||
return followOut;
|
||||
}
|
||||
@ -248,9 +255,10 @@ public final class GrammarAnalyzer {
|
||||
|
||||
final String prev = tableOut.put(new AbstractMap.SimpleEntry<>(leftside, sym), rightside);
|
||||
|
||||
Logger.logInfo("Add " + rightside + " to cell (" + leftside + ", " + sym + ") (" + sym
|
||||
+ " in first of " + rightside + ")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, "Overwritten " + prev + "!\n", GrammarAnalyzer.class);
|
||||
Logger.logInfo("Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfo(" :: Add " + rightside + " to cell (" + leftside + ", " + sym + ") (" + sym
|
||||
+ " in \"first(" + rightside + ")\")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, " :: Overwritten " + prev + "!", GrammarAnalyzer.class);
|
||||
}
|
||||
|
||||
final Set<String> followLeftside = this.follow(leftside);
|
||||
@ -263,9 +271,10 @@ public final class GrammarAnalyzer {
|
||||
|
||||
final String prev = tableOut.put(new AbstractMap.SimpleEntry<>(leftside, sym), rightside);
|
||||
|
||||
Logger.logInfo("Add " + rightside + " to cell (" + leftside + ", " + sym + ") (" + sym
|
||||
+ " in follow of " + leftside + ")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, "Overwritten " + prev + "!\n", GrammarAnalyzer.class);
|
||||
Logger.logInfo("Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfo(" :: Add " + rightside + " to cell (" + leftside + ", " + sym + ") (" + sym
|
||||
+ " in \"follow(" + leftside + ")\")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, " :: Overwritten " + prev + "!", GrammarAnalyzer.class);
|
||||
}
|
||||
|
||||
if (followLeftside.contains("$")) {
|
||||
@ -273,10 +282,11 @@ public final class GrammarAnalyzer {
|
||||
|
||||
final String prev = tableOut.put(new AbstractMap.SimpleEntry<>(leftside, "$"), rightside);
|
||||
|
||||
Logger.logInfo("Add " + rightside + " to cell (" + leftside
|
||||
+ ", $) (epsilon in first of " + rightside + " and $ in follow of "
|
||||
+ leftside + ")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, "Overwritten " + prev + "!\n", GrammarAnalyzer.class);
|
||||
Logger.logInfo("Rule: \"" + leftside + " -> " + rightside + "\"", GrammarAnalyzer.class);
|
||||
Logger.logInfo(" :: Add " + rightside + " to cell (" + leftside
|
||||
+ ", $) (epsilon in \"first(" + rightside + ")\" and $ in \"follow("
|
||||
+ leftside + ")\")", GrammarAnalyzer.class);
|
||||
Logger.logInfoNullable(prev, " :: Overwritten " + prev + "!", GrammarAnalyzer.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,8 +294,8 @@ public final class GrammarAnalyzer {
|
||||
|
||||
final ParsingTable parsingTable = new ParsingTable(this.grammar, tableOut);
|
||||
|
||||
Logger.logInfo("ParsingTable:\n" + parsingTable, GrammarAnalyzer.class);
|
||||
Logger.logDebug(" :: Parse-table initialized successfully", GrammarAnalyzer.class);
|
||||
Logger.logInfo("ParsingTable: " + parsingTable, GrammarAnalyzer.class);
|
||||
|
||||
return parsingTable;
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ public final class TypeChecker {
|
||||
|
||||
final String literalType = getLiteralType(root.getName());
|
||||
|
||||
Logger.logInfo("Type " + literalType + " for Node:\n" + root, TypeChecker.class);
|
||||
Logger.logInfo("Register type \"" + literalType + "\" for node \"" + root.getName() + ": "
|
||||
+ root.getValue() + "\"", TypeChecker.class);
|
||||
|
||||
nodeTable.put(root, literalType);
|
||||
return;
|
||||
@ -51,7 +52,8 @@ public final class TypeChecker {
|
||||
|
||||
final String exprType = table.getMethodReturnType(root.getValue());
|
||||
|
||||
Logger.logInfo("Type " + exprType + " for Node:\n" + root, TypeChecker.class);
|
||||
Logger.logInfo("Register type \"" + exprType + "\" for node \"" + root.getName() + "\"\n"
|
||||
+ root.nodePrint("\t\t"), TypeChecker.class);
|
||||
|
||||
nodeTable.put(root, exprType);
|
||||
} else if ("par_expr".equals(root.getName())) {
|
||||
@ -65,7 +67,8 @@ public final class TypeChecker {
|
||||
|
||||
final String identifierType = table.getSymbolType(root.getValue());
|
||||
|
||||
Logger.logInfo("Type " + identifierType + " for Node:\n" + root, TypeChecker.class);
|
||||
Logger.logInfo("Register type \"" + identifierType + "\" for node \"" + root.getName() + ": "
|
||||
+ root.getValue() + "\"", TypeChecker.class);
|
||||
|
||||
nodeTable.put(root, identifierType);
|
||||
}
|
||||
@ -83,7 +86,7 @@ public final class TypeChecker {
|
||||
final SyntaxTreeNode literalNode = root.getChildren().get(0);
|
||||
final String literalType = nodeTable.get(literalNode);
|
||||
|
||||
Logger.logInfo("Validating Assignment: " + identifierType + ": " + identifier + " = " + literalType, TypeChecker.class);
|
||||
Logger.logInfo("Validating assignment: \"" + identifier + "\" -> \"" + identifierType + "\" = \"" + literalType + "\"", TypeChecker.class);
|
||||
|
||||
if (!literalType.equals(identifierType)) {
|
||||
Logger.logError("Line " + root.getLine() + " Typeerror: Can't assign [" + literalNode.getValue()
|
||||
@ -96,7 +99,7 @@ public final class TypeChecker {
|
||||
private static void validateExpression(SyntaxTreeNode root, TypeTable table, Map<SyntaxTreeNode, String> nodeTable) {
|
||||
final String op = root.getValue();
|
||||
|
||||
Logger.logInfo("Validating Expression: " + root.getValue(), TypeChecker.class);
|
||||
Logger.logInfo("Validating expression: \"" + root.getValue() + "\"\n" + root.nodePrint("\t\t"), TypeChecker.class);
|
||||
|
||||
if (root.isEmpty()) {
|
||||
// Keine Kinder
|
||||
|
@ -86,7 +86,7 @@ public final class TypeTable {
|
||||
if ("declaration".equals(root.getName())) {
|
||||
final SyntaxTreeNode child = root.getChildren().get(0);
|
||||
|
||||
Logger.logInfo("Adding Entry " + child.getValue() + " -> " + root.getValue(), TypeTable.class);
|
||||
Logger.logInfo("Adding Entry: \"" + child.getValue() + "\" -> \"" + root.getValue() + "\"", TypeTable.class);
|
||||
final String oldEntry = table.put(child.getValue(), root.getValue());
|
||||
|
||||
if (oldEntry != null) {
|
||||
|
@ -8,7 +8,7 @@ public final class Logger {
|
||||
|
||||
private static final boolean LOG_ENABLED = true;
|
||||
private static final boolean LOG_EXCEPTIONS = false;
|
||||
private static final int LOG_LEVEL = 1; // 0 = ERROR, 1 = DEBUG, 2 = INFO
|
||||
private static final int LOG_LEVEL = 2; // 0 = ERROR, 1 = DEBUG, 2 = INFO
|
||||
|
||||
private static final Map<String, Boolean> packages;
|
||||
|
||||
@ -21,14 +21,15 @@ public final class Logger {
|
||||
Map.entry("codegen.analysis", true),
|
||||
Map.entry("codegen.analysis.dataflow", true),
|
||||
Map.entry("codegen.analysis.liveness", true),
|
||||
Map.entry("codegen", false));
|
||||
Map.entry("codegen", true));
|
||||
}
|
||||
|
||||
private Logger() {}
|
||||
|
||||
private static void log(String message, Class clazz) {
|
||||
if (LOG_ENABLED
|
||||
&& packages.containsKey(clazz.getPackageName()) && packages.get(clazz.getPackageName()).equals(true)) {
|
||||
&& (packages.containsKey(clazz.getPackageName()) && packages.get(clazz.getPackageName()).equals(true))
|
||||
|| "StupsCompiler".equals(clazz.getName())) {
|
||||
System.out.printf("%-75s\t(%s)%n", message, clazz.getName());
|
||||
|
||||
} else if (LOG_ENABLED && !packages.containsKey(clazz.getPackageName())) {
|
||||
|
Reference in New Issue
Block a user