Commit 074f6dc0 authored by Michael Schwarz's avatar Michael Schwarz

Aborting resolution instead of crashing if user creates cycle.

parent bf2d3139
......@@ -69,6 +69,7 @@ import de.tum.in.www2.cupplugin.editors.Jumper;
import de.tum.in.www2.cupplugin.editors.RevisionManager;
import de.tum.in.www2.cupplugin.model.ICupParserLaLrChangeObserver;
import de.tum.in.www2.cupplugin.model.Model;
import de.tum.in.www2.cupplugin.views.CupConflictsView.PrecedenceCyclicException;
public class CupConflictsView extends FailableView implements ICupEditorPageVisibility,
ICupParserLaLrChangeObserver, IRegisterForControllerChanges {
......@@ -87,7 +88,7 @@ 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
// 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?
......@@ -155,7 +156,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
public void addPrecedence(terminal higher,terminal lower){
public void addPrecedence(terminal higher,terminal lower) throws PrecedenceCyclicException{
// Make sure all terminals are represented within the precs
if(!precs.containsKey(higher)){
......@@ -168,9 +169,9 @@ 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)){
// Insert all speculative edges that are outgoing from the current node
// we need those now
edges.get(higher).addAll(speculativeEdges.get(higher));
}
......@@ -178,7 +179,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
edges.get(lower).add(higher);
if(!isAcyclic()){
throw new IllegalStateException("Horrible things lurk here");
throw new PrecedenceCyclicException();
}
for(ConflictPanel c : conflictPanels){
......@@ -243,7 +244,6 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
return false;
}
//TODO: topological sort of all precedences (probably reverse)
private void topSort(){
result = new LinkedList<>();
tarjanNodeInfos = new HashMap<>();
......@@ -283,9 +283,9 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
public String precsToInsert(){
public String precsToInsert() throws PrecedenceCyclicException{
if(!isAcyclic()){
throw new IllegalStateException("Expected result to be acyclic.");
throw new PrecedenceCyclicException();
}
topSort();
......@@ -383,6 +383,10 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
class PrecedenceCyclicException extends Exception{
}
class ShiftReduceDetails {
terminal shift,reduce;
boolean shiftAffectsOthers,reduceAffectsOthers;
......@@ -769,8 +773,6 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
//What if dropdown switched back to choose?
public void markIfAffected(PrecedenceToInsert pti){
if(conflict instanceof ShiftReduceConflict && pti.isAffected(srdetails)){
......@@ -894,7 +896,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
};
private SelectionListener resolutionBoxSelected = new SelectionListener() {
......@@ -934,11 +936,33 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
if(resolutionOptions.getSelectionIndex() == 1){ //Shift
currentPrecs.addPrecedence(srdetails.shift, srdetails.reduce);
try {
currentPrecs.addPrecedence(srdetails.shift, srdetails.reduce);
} catch (PrecedenceCyclicException e1) {
Shell shell = new Shell(Display.getCurrent());
MessageBox box = new MessageBox(shell,SWT.ICON_WARNING | SWT.OK);
box.setText("Information");
box.setMessage("These precedences are inconsistent. (Cyclic). Abort.");
box.open();
abortConnectedResolution();
return;
}
}
if(resolutionOptions.getSelectionIndex() == 2){ // Reduce
currentPrecs.addPrecedence(srdetails.reduce, srdetails.shift);
try {
currentPrecs.addPrecedence(srdetails.reduce, srdetails.shift);
} catch (PrecedenceCyclicException e1) {
Shell shell = new Shell(Display.getCurrent());
MessageBox box = new MessageBox(shell,SWT.ICON_WARNING | SWT.OK);
box.setText("Information");
box.setMessage("These precedences are inconsistent. (Cyclic). Abort..");
box.open();
abortConnectedResolution();
return;
}
}
}
......@@ -1156,6 +1180,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private void applyConnectedResolution(){
// Conflicts are part of current connected conflicts that are not resolved yet.
for(ConflictPanel p: conflictPanels){
if(p.partOfCurrentConnected){
if(p.resolutionOptions.getSelectionIndex() == 0){
......@@ -1177,8 +1202,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
int positionForPrec = 0;
if (r.precedences.size() == 0) {
// Precedences are located immediately after the last symbol
// decl
// Precedences are located immediately after the last symbol decl
positionForPrec = r.symbols.get(r.symbols.size() - 1).getEnd().getOffsetFromStart();
toInsert = "\n\n//Precedences added by Eclipse plugin\n" + toInsert;
} else {
......@@ -1193,6 +1217,9 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PrecedenceCyclicException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
abortConnectedResolution();
......
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