Code Should work now: P.S. Please god

This commit is contained in:
Mann Patel
2025-10-28 23:00:29 -06:00
parent 4c857942db
commit 41395648e3
2 changed files with 48 additions and 72 deletions

View File

@@ -25,7 +25,6 @@ public class LCA_JP1_0_0 {
System.out.println("Usage: java LCA_JP1_0_0 <JavaSourceFile>"); System.out.println("Usage: java LCA_JP1_0_0 <JavaSourceFile>");
return; return;
} }
System.out.println("WELCOME TO THE JUNGLE");
FileInputStream in = new FileInputStream(new File(args[0])); FileInputStream in = new FileInputStream(new File(args[0]));
CompilationUnit cu = JavaParser.parse(in); CompilationUnit cu = JavaParser.parse(in);
in.close(); in.close();
@@ -62,12 +61,12 @@ public class LCA_JP1_0_0 {
visitBlockStmt(body); visitBlockStmt(body);
} }
// Connect the last block to exit if not already connected // Connect last block to exit if not already connected
if (currentBlock != null && currentBlock != exitNode) { if (currentBlock != null && currentBlock != exitNode) {
addEdge(currentBlock, exitNode, ""); addEdge(currentBlock, exitNode, "");
} }
//new function Print CFG // Print CFG
printCFG(n.getName()); printCFG(n.getName());
} }
@@ -108,6 +107,7 @@ public class LCA_JP1_0_0 {
addEdge(currentBlock, exprNode, ""); addEdge(currentBlock, exprNode, "");
currentBlock = exprNode; currentBlock = exprNode;
// Track constant like "int v = 5" or "v = 5"
String stmtStr = stmt.toString().trim(); String stmtStr = stmt.toString().trim();
if (stmtStr.contains("=") && !stmtStr.contains("==")) { if (stmtStr.contains("=") && !stmtStr.contains("==")) {
try { try {
@@ -126,8 +126,7 @@ public class LCA_JP1_0_0 {
int value = Integer.parseInt(valuePart); int value = Integer.parseInt(valuePart);
constantValues.put(varName, value); constantValues.put(varName, value);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Not a constant, remove from tracking constantValues.remove(varName); // Not a constant, remove from tracking
constantValues.remove(varName);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@@ -139,21 +138,16 @@ public class LCA_JP1_0_0 {
private void visitIfStmt(IfStmt stmt) { private void visitIfStmt(IfStmt stmt) {
// Evaluate condition if possible // Evaluate condition if possible
String condStr = stmt.getCondition().toString(); String condStr = stmt.getCondition().toString();
String evaluatedCond = evaluateCondition(condStr); String edgeLabel = evaluateConditionForEdge(condStr);
// Determine if condition is always true or false // Create condition node
boolean alwaysTrue = evaluatedCond.contains("TRUE"); CFGNode condNode = new CFGNode("if (" + condStr + ")");
boolean alwaysFalse = evaluatedCond.contains("FALSE");
// Create condition node with evaluation result
CFGNode condNode = new CFGNode("if (" + condStr + ")" + evaluatedCond);
currCFG.addVertex(condNode); currCFG.addVertex(condNode);
addEdge(currentBlock, condNode, ""); addEdge(currentBlock, condNode, "");
CFGNode mergeNode = new CFGNode("MERGE_IF"); CFGNode mergeNode = new CFGNode("MERGE_IF");
currCFG.addVertex(mergeNode); currCFG.addVertex(mergeNode);
// Save the condition node to connect branches
CFGNode savedCond = condNode; CFGNode savedCond = condNode;
// Then branch // Then branch
@@ -163,22 +157,19 @@ public class LCA_JP1_0_0 {
visitStatement(thenStmt); visitStatement(thenStmt);
} }
// Connect then branch to merge
CFGNode thenEnd = currentBlock; CFGNode thenEnd = currentBlock;
if (thenEnd != null && thenEnd != savedCond) { if (thenEnd != null && thenEnd != savedCond) {
addEdge(thenEnd, mergeNode, ""); addEdge(thenEnd, mergeNode, "");
} }
// Add labeled edge from condition to then branch // Label then branch edge if we evaluated it
// Show "T" when condition is ALWAYS TRUE if (!edgeLabel.isEmpty()) {
if (alwaysTrue) {
// Find the edge to the then branch and label it
Set<CFGEdge> edges = new HashSet<CFGEdge>(currCFG.outgoingEdgesOf(savedCond)); Set<CFGEdge> edges = new HashSet<CFGEdge>(currCFG.outgoingEdgesOf(savedCond));
for (CFGEdge e : edges) { for (CFGEdge e : edges) {
CFGNode target = currCFG.getEdgeTarget(e); CFGNode target = currCFG.getEdgeTarget(e);
if (target != mergeNode) { if (target != mergeNode) {
currCFG.removeEdge(e); currCFG.removeEdge(e);
addEdge(savedCond, target, "T"); addEdge(savedCond, target, edgeLabel);
break; break;
} }
} }
@@ -193,35 +184,15 @@ public class LCA_JP1_0_0 {
if (elseEnd != null && elseEnd != savedCond) { if (elseEnd != null && elseEnd != savedCond) {
addEdge(elseEnd, mergeNode, ""); addEdge(elseEnd, mergeNode, "");
} }
// Add labeled edge from condition to else branch
// Show "F" when condition is ALWAYS FALSE
if (alwaysFalse) {
Set<CFGEdge> edges = new HashSet<CFGEdge>(currCFG.outgoingEdgesOf(savedCond));
for (CFGEdge e : edges) {
CFGNode target = currCFG.getEdgeTarget(e);
if (target != mergeNode && e.getLabel() == null) {
currCFG.removeEdge(e);
addEdge(savedCond, target, "F");
break;
}
}
} else {
// Normal case - else gets F label
addEdge(savedCond, mergeNode, "F");
}
} else { } else {
// No else branch - always label this F
addEdge(savedCond, mergeNode, "F"); addEdge(savedCond, mergeNode, "F");
} }
currentBlock = mergeNode; currentBlock = mergeNode;
} }
// *** CHANGE 4: NEW METHOD - Evaluate condition based on tracked constant values *** private String evaluateConditionForEdge(String condition) {
private String evaluateCondition(String condition) {
try { try {
// Handle simple comparisons like "v == 5", "v > 5", "v < 5"
String[] operators = {"==", "!=", ">=", "<=", ">", "<"}; String[] operators = {"==", "!=", ">=", "<=", ">", "<"};
for (String op : operators) { for (String op : operators) {
@@ -231,27 +202,19 @@ public class LCA_JP1_0_0 {
String leftStr = parts[0].trim(); String leftStr = parts[0].trim();
String rightStr = parts[1].trim(); String rightStr = parts[1].trim();
Integer leftVal = null; Integer leftVal = constantValues.get(leftStr);
Integer rightVal = null; Integer rightVal = constantValues.get(rightStr);
// Try to get value from constants map or parse directly if (leftVal == null) {
if (constantValues.containsKey(leftStr)) { try { leftVal = Integer.parseInt(leftStr); }
leftVal = constantValues.get(leftStr); catch (NumberFormatException e) {}
} else {
try {
leftVal = Integer.parseInt(leftStr);
} catch (NumberFormatException e) {}
} }
if (constantValues.containsKey(rightStr)) { if (rightVal == null) {
rightVal = constantValues.get(rightStr); try { rightVal = Integer.parseInt(rightStr); }
} else { catch (NumberFormatException e) {}
try {
rightVal = Integer.parseInt(rightStr);
} catch (NumberFormatException e) {}
} }
// If we have both values, evaluate
if (leftVal != null && rightVal != null) { if (leftVal != null && rightVal != null) {
boolean result = false; boolean result = false;
if (op.equals("==")) result = leftVal.equals(rightVal); if (op.equals("==")) result = leftVal.equals(rightVal);
@@ -261,16 +224,14 @@ public class LCA_JP1_0_0 {
else if (op.equals(">=")) result = leftVal >= rightVal; else if (op.equals(">=")) result = leftVal >= rightVal;
else if (op.equals("<=")) result = leftVal <= rightVal; else if (op.equals("<=")) result = leftVal <= rightVal;
return " [ALWAYS " + (result ? "TRUE" : "FALSE") + "]"; return result ? "T" : "F";
} }
} }
break; // Found operator, don't check others break;
} }
} }
} catch (Exception e) { } catch (Exception e) {}
// Evaluation failed return "";
}
return ""; // Cannot determine
} }
private void visitForStmt(ForStmt stmt) { private void visitForStmt(ForStmt stmt) {
@@ -382,35 +343,27 @@ public class LCA_JP1_0_0 {
} }
private void printCFG(String methodName) { private void printCFG(String methodName) {
// Grammar: "CFG" SPACE GraphName ":" NEWLINE
System.out.print("CFG "); System.out.print("CFG ");
System.out.print(methodName); System.out.print(methodName);
System.out.print(":"); System.out.print(":");
System.out.println(); System.out.println();
// Get all vertices and sort by ID
Set<CFGNode> vertexSet = currCFG.vertexSet(); Set<CFGNode> vertexSet = currCFG.vertexSet();
List<CFGNode> nodes = new ArrayList<CFGNode>(vertexSet); List<CFGNode> nodes = new ArrayList<CFGNode>(vertexSet);
// Sort nodes by ID
Collections.sort(nodes, new Comparator<CFGNode>() { Collections.sort(nodes, new Comparator<CFGNode>() {
public int compare(CFGNode n1, CFGNode n2) { public int compare(CFGNode n1, CFGNode n2) {
return n1.getID() - n2.getID(); return n1.getID() - n2.getID();
} }
}); });
// Grammar: (SPACE SPACE SPACE SPACE Node NEWLINE)*
for (CFGNode node : nodes) { for (CFGNode node : nodes) {
// Four spaces System.out.print("\t");
System.out.print(" ");
// "node" SPACE IDENTIFIER ":" LABEL SPACE
System.out.print("node "); System.out.print("node ");
System.out.print(node.getID()); System.out.print(node.getID());
System.out.print(": "); System.out.print(": ");
System.out.print(node.getLabel()); System.out.print(node.getLabel());
System.out.print(" "); System.out.print(" ");
// ("edge" SPACE LABEL SPACE IDENTIFIER ";" SPACE)*
Set<CFGEdge> outEdges = currCFG.outgoingEdgesOf(node); Set<CFGEdge> outEdges = currCFG.outgoingEdgesOf(node);
for (CFGEdge edge : outEdges) { for (CFGEdge edge : outEdges) {
CFGNode target = currCFG.getEdgeTarget(edge); CFGNode target = currCFG.getEdgeTarget(edge);

View File

@@ -1,5 +1,28 @@
# How shalt thou compile, with patience and practice # How shalt thou compile, with patience and practice
1. Compile thy code 1. Compile thy code
`javac -cp .:javaparser-1.0.0.jar:./lib/jgrapht-core-1.5.2.jar:./lib/jgrapht-io-1.5.2.jar:./lib/apfloat-1.10.1.jar:./lib/jheaps-0.14.jar CFGGraph/*.java LCA_JP1_0_0.java` `javac -cp .:javaparser-1.0.0.jar:./lib/jgrapht-core-1.5.2.jar:./lib/jgrapht-io-1.5.2.jar:./lib/apfloat-1.10.1.jar:./lib/jheaps-0.14.jar CFGGraph/*.java LCA_JP1_0_0.java`
`javac -cp .:javaparser-1.0.0.jar:./lib/* CFGGraph/*.java LCA_JP1_0_0.java`
2. Now move forth to victory 2. Now move forth to victory
`java -cp .:javaparser-1.0.0.jar:./lib/jgrapht-core-1.5.2.jar:./lib/jgrapht-io-1.5.2.jar:./lib/apfloat-1.10.1.jar:./lib/jheaps-0.14.jar LCA_JP1_0_0 Test.java` `java -cp .:javaparser-1.0.0.jar:./lib/jgrapht-core-1.5.2.jar:./lib/jgrapht-io-1.5.2.jar:./lib/ apfloat-1.10.1.jar:./lib/jheaps-0.14.jar LCA_JP1_0_0 Test.java`
`java -cp .:javaparser-1.0.0.jar:./lib/* LCA_JP1_0_0 Test.java`
3. PS: On Windows, replace `:` with `;` and `/` with `\` in paths
Node 1 (ENTRY): Created FIRST, so it gets ID = 1
Node 2 (EXIT): Created SECOND, so it gets ID = 2
Then we build the rest of the method body starting from node 3
Why we need them:
ENTRY marks where the method starts (before any code executes)
EXIT marks where the method ends (after return statements)
Helps with analysis - clear start/end points for control flow
```java
if (val == 5) { // node 8
val = 6; // node 10
} // node 9: MERGE_IF
```
**Node 9 (MERGE_IF) → edge 14**:
- Node 9 is where the FIRST if statement merges (after `val = 6;`)
- After the merge, control flow continues to the NEXT statement