Commit 4d616b09 authored by Michael Schwarz's avatar Michael Schwarz 🤔
Browse files

Preparations for precedence graph

parent 64a908b8
...@@ -5,6 +5,7 @@ import java.util.EnumSet; ...@@ -5,6 +5,7 @@ import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
...@@ -86,16 +87,22 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -86,16 +87,22 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
//TODO: Can I do this? Does the terminal class properly implement all the required things? //TODO: Can I do this? Does the terminal class properly implement all the required things?
private HashMap<terminal,Precedence.Type> precs = new HashMap<>(); private HashMap<terminal,Precedence.Type> precs = new HashMap<>();
// Edges are stored in reverse order (i.e. there is a edge from a to b iff b has a higher
// precedence than a)
private HashMap<terminal,Set<terminal>> edges = new HashMap<>();
public boolean isResolvedInFavorOfShift(ShiftReduceDetails srd){ public boolean isResolvedInFavorOfShift(ShiftReduceDetails srd){
if(!srd.reduce.equals(srd.shift)) if(!srd.reduce.equals(srd.shift))
return precs.containsKey(srd.shift); //TODO: Check if precedence set for terminal at all
return hasPrecedence(srd.reduce,srd.shift);
else else
return precs.get(srd.shift) == Precedence.Type.Right; return precs.get(srd.shift) == Precedence.Type.Right;
} }
public boolean isResolvedInFavorOfReduce(ShiftReduceDetails srd) { public boolean isResolvedInFavorOfReduce(ShiftReduceDetails srd) {
if(!srd.reduce.equals(srd.shift)) if(!srd.reduce.equals(srd.shift))
return precs.containsKey(srd.reduce); //TODO: Check if precedence set for terminal at all
return hasPrecedence(srd.reduce,srd.shift);
else else
return precs.get(srd.shift) == Precedence.Type.Left; return precs.get(srd.shift) == Precedence.Type.Left;
} }
...@@ -111,16 +118,67 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -111,16 +118,67 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
return precs.containsKey(srd.shift) || precs.containsKey(srd.reduce); return precs.containsKey(srd.shift) || precs.containsKey(srd.reduce);
} }
// Add with non-set precedence // Add with non-set assoc
public void add(terminal t){ public void add(terminal t){
// We use NoPrec as a placeholder // We use NoPrec as a placeholder
precs.put(t, Precedence.Type.NoPrec); precs.put(t, Precedence.Type.NoPrec);
edges.put(t, new HashSet<>());
for(ConflictPanel c : conflictPanels){
c.markIfAffected(this);
}
}
public void addPrecedence(terminal higher,terminal lower){
// Make sure all terminals are represented within the precs
if(!precs.containsKey(higher)){
precs.put(higher, Precedence.Type.NoPrec);
edges.put(higher, new HashSet<>());
}
if(!precs.containsKey(lower)){
precs.put(lower, Precedence.Type.NoPrec);
edges.put(lower, new HashSet<>());
}
// Insert edge
edges.get(lower).add(higher);
for(ConflictPanel c : conflictPanels){ for(ConflictPanel c : conflictPanels){
c.markIfAffected(this); c.markIfAffected(this);
} }
} }
private boolean hasPrecedence(terminal t,terminal over){
// This works because we have guarantee that the graph is a DAG
HashSet<terminal> toCheck = new HashSet<>();
toCheck.addAll(edges.get(over));
// TODO:Sure ?
if(toCheck.size() == 0){
return true;
}
while(toCheck.size() > 0){
if(toCheck.contains(t)){
return true;
}
else {
HashSet<terminal> next = new HashSet<>();
for(terminal x : toCheck){
next.addAll(edges.get(x));
}
toCheck = next;
}
}
return false;
}
public void setAssoc(terminal t,Precedence.Type p){ public void setAssoc(terminal t,Precedence.Type p){
if(precs.get(t) != Precedence.Type.NoPrec){ if(precs.get(t) != Precedence.Type.NoPrec){
throw new IllegalStateException(); throw new IllegalStateException();
...@@ -131,6 +189,10 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -131,6 +189,10 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
c.markIfAffected(this); c.markIfAffected(this);
} }
} }
public boolean isActive(){
return precs.size() != 0;
}
} }
class ShiftReduceDetails { class ShiftReduceDetails {
...@@ -519,6 +581,8 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -519,6 +581,8 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
} }
//What if dropdown switched back to choose?
public void markIfAffected(PrecedenceToInsert pti){ public void markIfAffected(PrecedenceToInsert pti){
if(conflict instanceof ShiftReduceConflict && pti.isAffected(srdetails)){ if(conflict instanceof ShiftReduceConflict && pti.isAffected(srdetails)){
...@@ -590,6 +654,11 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -590,6 +654,11 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
if(resolutionOptions.getSelectionIndex() == 0){ if(resolutionOptions.getSelectionIndex() == 0){
return; return;
} }
if(currentPrecs.isActive()) {
// That should not happen, if we are inside a connected conflict, button is disabled
return;
}
if(!srdetails.reduce.equals(srdetails.shift)){ if(!srdetails.reduce.equals(srdetails.shift)){
...@@ -641,7 +710,12 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -641,7 +710,12 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
@Override @Override
public void widgetSelected(SelectionEvent e) { public void widgetSelected(SelectionEvent e) {
if(partOfCurrentConnected && srdetails.reduce.equals(srdetails.shift)){ if(!partOfCurrentConnected) {
return;
}
// We need to insert a assoc
if(srdetails.reduce.equals(srdetails.shift)){
if(resolutionOptions.getSelectionIndex() == 1) { //Shift if(resolutionOptions.getSelectionIndex() == 1) { //Shift
forceEnableDropdown = true; forceEnableDropdown = true;
currentPrecs.setAssoc(srdetails.shift,Precedence.Type.Right); currentPrecs.setAssoc(srdetails.shift,Precedence.Type.Right);
...@@ -651,6 +725,27 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi ...@@ -651,6 +725,27 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
currentPrecs.setAssoc(srdetails.shift,Precedence.Type.Left); currentPrecs.setAssoc(srdetails.shift,Precedence.Type.Left);
} }
} }
else {
if(resolutionOptions.getSelectionIndex() == 1 && currentPrecs.isResolvedInFavorOfShift(srdetails)){
// Shift is current solution, Shift is desired
// Do nothing
return;
}
if(resolutionOptions.getSelectionIndex() == 2 && currentPrecs.isResolvedInFavorOfReduce(srdetails)){
// Reduce is current solution, Reduce is desired
// Do nothing
return;
}
if(resolutionOptions.getSelectionIndex() == 1){ //Shift
currentPrecs.addPrecedence(srdetails.shift, srdetails.reduce);
}
if(resolutionOptions.getSelectionIndex() == 2){ // Reduce
currentPrecs.addPrecedence(srdetails.reduce, srdetails.shift);
}
}
} }
@Override @Override
......
Supports Markdown
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