Skip to content

Commit

Permalink
Testing GraphPatternMatcher
Browse files Browse the repository at this point in the history
Adding missing files
  • Loading branch information
avishek-sen-gupta committed Jul 12, 2024
1 parent 2106468 commit b77b55a
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public interface FlowNode {

void linkParentToChild(FlowNodeVisitor visitor, int level);
void accept(FlowNodeVisitor visitor, int level);
void accept(FlowNodeVisitor visitor, FlowNodeCondition stopCondition, int level);
void acceptUnvisited(FlowNodeVisitor visitor, int level);

List<? extends ParseTree> getChildren();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static void main(String[] args) throws IOException, InterruptedException
Record neo4jProgramRoot = sdk.findNodes(qualifier.astNodeCriteria(Map.of(TYPE, FlowNodeType.PROCEDURE_DIVISION_BODY.toString()))).getFirst();

// Summarises AST bottom-up
sdk.traverse(neo4jProgramRoot, new SummariseAction(advisor, sdk), CONTAINS);
// sdk.traverse(neo4jProgramRoot, new SummariseAction(advisor, sdk), CONTAINS);

// Builds data structures
dataStructures.accept(new Neo4JDataStructureVisitor(sdk, qualifier), null, n -> false, dataStructures);
Expand All @@ -77,6 +77,10 @@ public static void main(String[] args) throws IOException, InterruptedException
Record neo4jDataStructuresRoot = sdk.findNodes(qualifier.dataNodeSearchCriteria(Map.of(TYPE, "ROOT"))).getFirst();

// Summarises data structures
sdk.traverse(neo4jDataStructuresRoot, new DataStructureSummariseAction(advisor, sdk), CONTAINS);
// sdk.traverse(neo4jDataStructuresRoot, new DataStructureSummariseAction(advisor, sdk), CONTAINS);

GraphPatternMatcher visitor = new GraphPatternMatcher(sdk);
root.accept(visitor, node -> node.type() == FlowNodeType.SENTENCE, -1);
System.out.printf("Number of groups = %s%n", visitor.getMatches().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.smojol.analysis.graph;

import com.mojo.woof.GraphSDK;
import lombok.Getter;
import org.eclipse.lsp.cobol.core.CobolParser;
import org.smojol.common.flowchart.*;

import java.util.ArrayList;
import java.util.List;

public class GraphPatternMatcher implements FlowNodeVisitor {
private final GraphSDK sdk;
@Getter
private final List<List<FlowNode>> matches = new ArrayList<>();
private List<FlowNode> currentMatch = new ArrayList<>();

public GraphPatternMatcher(GraphSDK sdk) {
this.sdk = sdk;
}

@Override
public void visit(FlowNode node, List<FlowNode> outgoingNodes, List<FlowNode> incomingNodes, VisitContext context, FlowNodeService nodeService) {
System.out.println(String.format("Visiting %s", node));
if (node.type() == FlowNodeType.SENTENCE && node.astChildren().size() == 1 && node.astChildren().getFirst().type() == FlowNodeType.MOVE) {
registerMove(node);
return;
}
if (currentMatch.isEmpty()) return;
matches.add(currentMatch);
currentMatch = new ArrayList<>();
}

private void registerMove(FlowNode node) {
currentMatch.add(node);
}

@Override
public void visitParentChildLink(FlowNode parent, FlowNode internalTreeRoot, VisitContext ctx, FlowNodeService nodeService) {
}

@Override
public void visitParentChildLink(FlowNode parent, FlowNode internalTreeRoot, VisitContext ctx, FlowNodeService nodeService, FlowNodeCondition hideStrategy) {
}

@Override
public void visitControlTransfer(FlowNode from, FlowNode to, VisitContext visitContext) {
}

@Override
public FlowNodeVisitor newScope(FlowNode enclosingScope) {
return this;
}

@Override
public void group(FlowNode root) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import java.util.List;

import static com.mojo.woof.NodeRelations.*;

public class Neo4JFlowCFGVisitor implements FlowNodeVisitor {
private final GraphSDK sdk;
private final NodeSpecBuilder qualifier;
Expand Down Expand Up @@ -49,6 +47,7 @@ public void visitControlTransfer(FlowNode from, FlowNode to, VisitContext visitC
Record destinationRecord = newOrExisting(to);
sdk.jumpsTo(sourceRecord, destinationRecord);
}

@Override
public FlowNodeVisitor newScope(FlowNode enclosingScope) {
return this;
Expand Down
10 changes: 9 additions & 1 deletion smojol-toolkit/src/main/java/org/smojol/ast/CobolFlowNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,20 @@ public void accept(FlowNodeVisitor visitor, int level) {
acceptUnvisited(visitor, level);
}

@Override
public void accept(FlowNodeVisitor visitor, FlowNodeCondition stopRecurseCondition, int level) {
acceptUnvisited(visitor, stopRecurseCondition, level);
}

public void acceptUnvisited(FlowNodeVisitor visitor, int level) {
// System.out.println("Current level: " + level);
visitor.visit(this, outgoingNodes, incomingNodes, new VisitContext(level), nodeService);
outgoingNodes.forEach(c -> c.accept(visitor, level));
}

public void acceptUnvisited(FlowNodeVisitor visitor, FlowNodeCondition stopCondition, int level) {
acceptUnvisited(visitor, level);
}

@Override
public void addIncomingNode(FlowNode flowNode) {
incomingNodes.add(flowNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ public void acceptUnvisited(FlowNodeVisitor visitor, int level) {
}
}

@Override
public void acceptUnvisited(FlowNodeVisitor visitor, FlowNodeCondition stopRecurseCondition, int level) {
visitor.visit(this, outgoingNodes, incomingNodes, new VisitContext(level), nodeService);
if (!stopRecurseCondition.apply(this) && internalTreeRoot != null) {
linkParentToChild(visitor, level);
FlowNode current = internalTreeRoot;
current.accept(visitor.newScope(this), stopRecurseCondition, level + 1);
}
outgoingNodes.forEach(c -> c.accept(visitor, stopRecurseCondition, level));
}

@Override
public FlowNode next(FlowNodeCondition nodeCondition, FlowNode startingNode, boolean isComplete) {
System.out.println("Moved up to " + executionContext.getClass() + executionContext.getText());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public void accept(FlowNodeVisitor visitor, int level) {

}

@Override
public void accept(FlowNodeVisitor visitor, FlowNodeCondition stopCondition, int level) {

}

@Override
public List<? extends ParseTree> getChildren() {
return List.of();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public FlowNode block(FlowNode node) {
if (containingGroups.isEmpty()) return node;
if (containingGroups.size() == 1) return containingGroups.getFirst();
// Filters out lower-level groups which are GenericStatement aggregations
// TODO: This is very similar to the OverlayVisitor's condition. Maybe some refactoring to isAtomicType() is needed
return containingGroups.stream().filter(g -> !isAtomic2(g)).findFirst().get();
return containingGroups.stream().filter(g -> !isAtomic(g)).findFirst().get();
}

public static boolean isAtomic(FlowNode node) {
Expand All @@ -32,8 +31,4 @@ public static boolean isAtomic(FlowNode node) {
node.getClass() == DivideFlowNode.class ||
node.getClass() == AddFlowNode.class;
}

private static boolean isAtomic2(GenericProcessingFlowNode g) {
return isAtomic(g);
}
}
5 changes: 5 additions & 0 deletions smojol-toolkit/src/main/java/org/smojol/ast/NullFlowNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public void accept(FlowNodeVisitor visitor, int level) {

}

@Override
public void accept(FlowNodeVisitor visitor, FlowNodeCondition stopCondition, int level) {

}

@Override
public List<? extends ParseTree> getChildren() {
return List.of();
Expand Down

0 comments on commit b77b55a

Please sign in to comment.