Commit d2e5e922 authored by Michael Schwarz's avatar Michael Schwarz

fix cycle detection

parent 79906bf4
......@@ -86,6 +86,9 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private PrecedenceToInsert currentPrecs;
class PrecedenceToInsert {
//TODO: The user can insert edges that contradict the thing we wanted in the end => Doesn't crash on cyclic
// Occurs because the first terminal is not inserted
//TODO: Can I do this? Does the terminal class properly implement all the required things?
private HashMap<terminal,Precedence.Type> precs = new HashMap<>();
......@@ -93,6 +96,9 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
// precedence than a)
private HashMap<terminal,Set<terminal>> edges = new HashMap<>();
// These need to be inserted whenever an edge that contains the key is to be inserted
private HashMap<terminal,Set<terminal>> speculativeEdges = new HashMap<>();
private int tarjanIndex;
private HashMap<terminal,TarjanNodeInfo> tarjanNodeInfos;
private Stack<terminal> tarjanStack;
......@@ -131,11 +137,16 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
// Add with non-set assoc
public void add(terminal t){
public void add(terminal t,terminal other){
// We use NoPrec as a placeholder
precs.put(t, Precedence.Type.NoPrec);
edges.put(t, new HashSet<>());
HashSet<terminal> spec = new HashSet<>();
spec.add(t);
speculativeEdges.put(other,spec);
for(ConflictPanel c : conflictPanels){
c.markIfAffected(this);
}
......@@ -154,9 +165,19 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
edges.put(lower, new HashSet<>());
}
// Insert all speculative edges that are outgoing from the current node
// we need those now
if(speculativeEdges.containsKey(higher)){
edges.get(higher).addAll(speculativeEdges.get(higher));
}
// Insert edge
edges.get(lower).add(higher);
if(!isAcylic()){
throw new IllegalStateException("Horrible things lurk here");
}
for(ConflictPanel c : conflictPanels){
c.markIfAffected(this);
}
......@@ -223,8 +244,24 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private boolean hasPrecedence(terminal t,terminal over){
if(!precs.containsKey(t) && !precs.containsKey(over)){
return false;
}
if(precs.containsKey(t) && !precs.containsKey(over)){
return true;
}
if(!precs.containsKey(t) && precs.containsKey(over)){
return false;
}
// Hereafter we know that both are in there
// This works because we have guarantee that the graph is a DAG
HashSet<terminal> toCheck = new HashSet<>();
if(edges.get(over).size() == 0){
return true;
}
toCheck.addAll(edges.get(over));
// TODO:Sure ?
......@@ -726,7 +763,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
return;
}
if(currentPrecs.isActive()) {
if(currentPrecs != null && currentPrecs.isActive()) {
// That should not happen, if we are inside a connected conflict, button is disabled
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment