Commit 3ad29e2d authored by Michael Schwarz's avatar Michael Schwarz

make topsort

parent b828a0ec
......@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
......@@ -79,7 +80,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private boolean isVisible;
private List<ConflictPanel> conflictPanels;
private Label countConflictsLabel, connectedResolutionLabel;
private Button connectedResolutionAbort;
private Button connectedResolutionAbort, connectedResolutionApply;
private ScrolledComposite scrolled;
private Composite list;
......@@ -109,6 +110,8 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
public int lowlink;
}
private LinkedList<Pair<terminal,Precedence.Type>> result;
public boolean isResolvedInFavorOfShift(ShiftReduceDetails srd){
if(!srd.reduce.equals(srd.shift))
//TODO: Check if precedence set for terminal at all
......@@ -174,7 +177,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
// Insert edge
edges.get(lower).add(higher);
if(!isAcylic()){
if(!isAcyclic()){
throw new IllegalStateException("Horrible things lurk here");
}
......@@ -183,7 +186,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
private boolean isAcylic(){
private boolean isAcyclic(){
tarjanIndex = 0;
tarjanNodeInfos = new HashMap<>();
tarjanStack = new Stack<>();
......@@ -241,7 +244,72 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
//TODO: topological sort of all precedences (probably reverse)
private void topSort(){
result = new LinkedList<>();
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){
topSortVisit(e.getKey());
}
}
}
private void topSortVisit(terminal t){
if(tarjanNodeInfos.get(t).onStack){
throw new IllegalStateException("Expected result to be acyclic.");
}
if(tarjanNodeInfos.get(t).index == -1){
tarjanNodeInfos.get(t).onStack = true;
for(terminal succ : edges.get(t)){
topSortVisit(succ);
}
tarjanNodeInfos.get(t).index = 1;
tarjanNodeInfos.get(t).onStack = false;
result.addFirst(new Pair<terminal,Precedence.Type>(t,precs.get(t)));
}
}
public String precsToInsert(){
if(!isAcyclic()){
throw new IllegalStateException("Expected result to be acyclic.");
}
topSort();
StringBuilder sb = new StringBuilder();
boolean first = true;
for(Pair<terminal,Precedence.Type> p : result){
if(first){
first = false;
}
else {
sb.append("\n");
}
sb.append("precedence ");
sb.append(p.getSecond().toString().toLowerCase());
sb.append(" ");
sb.append(p.getFirst().name());
sb.append("; // Inserted by Eclipse plugin");
}
return sb.toString();
}
private boolean hasPrecedence(terminal t,terminal over){
if(!precs.containsKey(t) && !precs.containsKey(over)){
......@@ -927,6 +995,21 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
});
this.connectedResolutionApply = new Button(list,SWT.PUSH);
this.connectedResolutionApply.setVisible(false);
this.connectedResolutionApply.setText("Apply");
this.connectedResolutionApply.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
applyConnectedResolution();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
refreshScrolledLayout();
}
......@@ -1032,7 +1115,6 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
private void beginConnectedResolution(){
Shell shell = new Shell(Display.getCurrent());
MessageBox box = new MessageBox(shell,SWT.ICON_WARNING | SWT.OK);
......@@ -1044,6 +1126,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
currentPrecs = new PrecedenceToInsert();
this.connectedResolutionLabel.setText("Currently resolving a set of conflicts that are connected.");
this.connectedResolutionAbort.setVisible(true);
this.connectedResolutionApply.setVisible(true);
refreshScrolledLayout();
}
......@@ -1051,6 +1134,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
currentPrecs = new PrecedenceToInsert();
this.connectedResolutionLabel.setText("");
this.connectedResolutionAbort.setVisible(false);
this.connectedResolutionApply.setVisible(false);
for(ConflictPanel c : conflictPanels){
c.connectedEditAborted();
......@@ -1058,6 +1142,34 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
refreshScrolledLayout();
}
private void applyConnectedResolution(){
try {
IDocument document = editor.getDocument();
ParserResult r = Model.getInstanceForDocument(document).getAstModel();
String toInsert = currentPrecs.precsToInsert();
int positionForPrec = 0;
if (r.precedences.size() == 0) {
// 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 {
positionForPrec = r.precedences.get(r.precedences.size() - 1).getRange().getBegin()
.getOffsetFromStart();
toInsert = toInsert + "\n";
}
document.replace(positionForPrec, 0, toInsert);
abortConnectedResolution();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void insertPrecedence(terminal terminal,Precedence.Type assoc){
try {
......
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