Commit 7af34a86 authored by Michael Schwarz's avatar Michael Schwarz

Better runtime for determining if a conflict affects others

parent 0027ef68
......@@ -85,6 +85,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private ScrolledComposite scrolled;
private Composite list;
private HashMap<terminal,Integer> terminalsAffectConflicts;
private PrecedenceToInsert currentPrecs;
class PrecedenceToInsert {
......@@ -718,10 +719,10 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
srdetails.shift = sourceOfShiftPrec;
srdetails.shiftAffectsOthers = insertingPrecAffectsOtherConflicts(crm,src,sourceOfShiftPrec);
srdetails.shiftAffectsOthers = insertingPrecAffectsOtherConflicts(sourceOfShiftPrec);
srdetails.reduce = sourceOfReducePrec;
srdetails.reduceAffectsOthers = insertingPrecAffectsOtherConflicts(crm,src,sourceOfReducePrec);
srdetails.reduceAffectsOthers = insertingPrecAffectsOtherConflicts(sourceOfReducePrec);
// RHS is only nonterminal and no %prec directive => sourceOfReducePrec == null
......@@ -1052,6 +1053,15 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
List<Conflict> conflicts = crm.getAllConflicts();
int size = conflicts.size();
matchPanelNumber(size);
terminalsAffectConflicts = new HashMap<>();
// Do this first, otherwise the affects others is wrong because it operates on a subset of actual terminals
for (int i = 0; i < size; i++) {
Conflict conflict = conflicts.get(i);
addToTerminalSet(crm,conflict);
}
for (int i = 0; i < size; i++) {
Conflict conflict = conflicts.get(i);
ConflictPanel panel = conflictPanels.get(i);
......@@ -1059,6 +1069,60 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
refreshScrolledLayout();
}
private void addToTerminalSet(ConflictResolutionManager crm,Conflict conflict){
if(conflict instanceof ShiftReduceConflict){
ShiftReduceConflict src = (ShiftReduceConflict)conflict;
terminal sourceOfShiftPrec = src.getTerminal();
terminal sourceOfReducePrec = null;
ProductionRight conflict1Ast = src.getConflictItem1()
.the_production().getAstNode();
// If the precedence is specifically set via %prec
if(conflict1Ast.hasSpecifiedPrecedence()){
sourceOfReducePrec = terminal.getShared(crm.getLaLrContext()).find(
conflict1Ast.getPrecedenceLike().getNameStringOrNull());
}
// Terminal defining precedence is the last one in the current production
else {
for(IProductionRightPart part : conflict1Ast.getList()){
if(part instanceof ProductionSymbolRef){
ProductionSymbolRef ppsr = (ProductionSymbolRef)part;
terminal candidate = terminal.getShared(crm.getLaLrContext()).find(
ppsr.getNameStringOrNull());
if(candidate != null){
sourceOfReducePrec = candidate;
}
}
}
}
if(terminalsAffectConflicts.containsKey(sourceOfShiftPrec)){
terminalsAffectConflicts.put(sourceOfShiftPrec, terminalsAffectConflicts.get(sourceOfShiftPrec)+1);
}
else{
terminalsAffectConflicts.put(sourceOfShiftPrec, 1);
}
// If both precs come from the same terminal, we only need to increment once (every conflict affects itself)
if(sourceOfReducePrec != null && !sourceOfReducePrec.equals(sourceOfShiftPrec)){
if(sourceOfReducePrec.toString().equals(sourceOfShiftPrec.toString())){
throw new IllegalStateException();
}
if(terminalsAffectConflicts.containsKey(sourceOfReducePrec)){
terminalsAffectConflicts.put(sourceOfReducePrec, terminalsAffectConflicts.get(sourceOfReducePrec)+1);
}
else{
terminalsAffectConflicts.put(sourceOfReducePrec, 1);
}
}
}
}
private void matchPanelNumber(int number) {
int excessPanels = this.conflictPanels.size() - number;
......@@ -1251,45 +1315,14 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
private boolean insertingPrecAffectsOtherConflicts(ConflictResolutionManager crm,ShiftReduceConflict intended,terminal t){
for(Conflict c : crm.getAllConflicts()){
if(c instanceof ShiftReduceConflict){
ShiftReduceConflict src = (ShiftReduceConflict)c;
if(!intended.equals(src)){
terminal sourceOfShiftPrec = src.getTerminal();
terminal sourceOfReducePrec = null;
ProductionRight conflict1Ast = src.getConflictItem1()
.the_production().getAstNode();
// If the precedence is specifically set via %prec
if(conflict1Ast.hasSpecifiedPrecedence()){
sourceOfReducePrec = terminal.getShared(crm.getLaLrContext()).find(
conflict1Ast.getPrecedenceLike().getNameStringOrNull());
}
// Terminal defining precedence is the last one in the current production
else {
for(IProductionRightPart part : conflict1Ast.getList()){
if(part instanceof ProductionSymbolRef){
ProductionSymbolRef ppsr = (ProductionSymbolRef)part;
terminal candidate = terminal.getShared(crm.getLaLrContext()).find(
ppsr.getNameStringOrNull());
if(candidate != null){
sourceOfReducePrec = candidate;
}
}
}
}
if(t.equals(sourceOfShiftPrec) || t.equals(sourceOfReducePrec)){
return true;
}
}
}
}
private boolean insertingPrecAffectsOtherConflicts(terminal t){
Integer affected = terminalsAffectConflicts.get(t);
return false;
if(affected== null){
return false;
}
else{
return affected != 1;
}
}
}
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