Commit 53a546d0 authored by Michael Schwarz's avatar Michael Schwarz 🤔
Browse files

Check if inserting precs / assocs affects other conflicts as well and

display this to the user
parent b53a2950
......@@ -361,6 +361,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
// RHS is only nonterminal and no %prec directive => sourceOfReducePrec == null
int reducePred = src.getConflictItem1().the_production().precedence_num();
int shiftPred = src.getTerminal().precedence_num();
......@@ -369,9 +370,38 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
if(sourceOfShiftPrec.equals(sourceOfReducePrec)) {
// If the precedence of the terminal and the production come from the same terminal
resolutionOptions.add("Shift (== make " + src.getTerminal().name() +" right associative");
resolutionOptions.add("Reduce (== make " + src.getTerminal().name() +" left associative");
}
// the thing we need to consider are assocs
if(!insertingPrecAffectsOtherConflicts(crm,src,sourceOfShiftPrec)){
resolutionOptions.add("Shift (make " + sourceOfShiftPrec.name() +" right associative)");
resolutionOptions.add("Reduce (make " + sourceOfShiftPrec.name() +" left associative)");
}
else {
resolutionOptions.add("Affects others: Shift (make " + sourceOfShiftPrec.name() +" right associative)");
resolutionOptions.add("Affects others: Reduce (make " + sourceOfShiftPrec.name() +" left associative)");
}
}
else {
// If the precedence of the terminal and the production come from different terminals
// we need to choose the precedence
if(!insertingPrecAffectsOtherConflicts(crm,src,sourceOfShiftPrec)) {
resolutionOptions.add("Shift (insert precedence for " + sourceOfShiftPrec.name() +")");
}
else {
resolutionOptions.add("Affects others: Shift (insert precedence for " + sourceOfShiftPrec.name() +")");
}
if(sourceOfReducePrec != null){
if(!insertingPrecAffectsOtherConflicts(crm,src,sourceOfReducePrec)) {
resolutionOptions.add("Reduce (insert precedence for " + sourceOfReducePrec.name() +")");
}
else{
resolutionOptions.add("Affects others: Reduce (insert precedence for " + sourceOfReducePrec.name() +")");
}
}
}
} else {
throw new RuntimeException("unexpected conflict type.");
}
......@@ -525,4 +555,45 @@ 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;
}
}
}
}
return false;
}
}
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