Commit 79906bf4 authored by Michael Schwarz's avatar Michael Schwarz

test if precs to be inserted are acylic

parent 4d616b09
......@@ -5,7 +5,9 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
......@@ -91,6 +93,16 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
// precedence than a)
private HashMap<terminal,Set<terminal>> edges = new HashMap<>();
private int tarjanIndex;
private HashMap<terminal,TarjanNodeInfo> tarjanNodeInfos;
private Stack<terminal> tarjanStack;
private class TarjanNodeInfo{
public int index;
public boolean onStack;
public int lowlink;
}
public boolean isResolvedInFavorOfShift(ShiftReduceDetails srd){
if(!srd.reduce.equals(srd.shift))
//TODO: Check if precedence set for terminal at all
......@@ -150,6 +162,66 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
private boolean isAcylic(){
tarjanIndex = 0;
tarjanNodeInfos = new HashMap<>();
tarjanStack = new Stack<>();
for(terminal t : precs.keySet()){
TarjanNodeInfo tni = new TarjanNodeInfo();
tni.onStack = false;
tni.index = -1;
tni.lowlink = -1;
tarjanNodeInfos.put(t, tni);
}
for(Entry<terminal, TarjanNodeInfo> e : tarjanNodeInfos.entrySet()){
if(e.getValue().index == -1){
if(strongConnect(e.getKey())){
return false;
}
}
}
return true;
}
private boolean strongConnect(terminal t){
TarjanNodeInfo node = tarjanNodeInfos.get(t);
node.index = tarjanIndex;
node.lowlink = tarjanIndex;
node.onStack = true;
tarjanIndex++;
tarjanStack.push(t);
for(terminal succ : edges.get(t)){
if(tarjanNodeInfos.get(succ).index == -1){
if(strongConnect(succ)){
return true;
}
node.lowlink = Math.min(node.lowlink,tarjanNodeInfos.get(succ).lowlink);
}
else if(tarjanNodeInfos.get(succ).onStack){
node.lowlink = Math.min(node.lowlink,tarjanNodeInfos.get(succ).index);
}
}
if(node.lowlink == node.index){
terminal w = tarjanStack.pop();
tarjanNodeInfos.get(w).onStack = false;
if(!w.equals(t)){
return true;
}
}
return false;
}
//TODO: topological sort of all precedences (probably reverse)
private boolean hasPrecedence(terminal t,terminal over){
// This works because we have guarantee that the graph is a DAG
HashSet<terminal> toCheck = new HashSet<>();
......@@ -174,8 +246,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
toCheck = next;
}
}
return false;
}
......
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