Commit 212bd004 authored by Michael Schwarz's avatar Michael Schwarz

resolving of RR conflicts works if each production has a single right

hand side and affects no others
parent 88c32f6f
......@@ -3,6 +3,7 @@ package de.tum.in.www2.cupplugin.views;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
......@@ -558,75 +559,105 @@ class ConflictPanel extends Composite {
return s.replace("(*)", "\u2022");
}
private SelectionListener resolutionButtonClick = new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e){ }
public void widgetSelected(SelectionEvent e){
if(!(conflict instanceof ShiftReduceConflict)) {
//DEBUG
cupConflictsView.moveItemToVeryEnd(((ReduceReduceConflict)conflict).getConflictItem1());
return;
}
if(resolutionOptions.getSelectionIndex() == 0){
private void resolutionButtonSRClick(){
if(cupConflictsView.currentPrecs != null && cupConflictsView.currentPrecs.isActive()) {
// That should not happen, if we are inside a connected conflict, button is disabled
return;
}
if(!srdetails.shiftAndReducePrecedenceFromSameTerminal()){
// The user wants to shift, but shifting affects other conflicts
if(srdetails.shiftAffectsOthers && resolutionOptions.getSelectionIndex() == 1){
cupConflictsView.beginConnectedResolution();
cupConflictsView.addFirstPrecedence(srdetails.shift,srdetails.reduce);
return;
}
if(cupConflictsView.currentPrecs != null && cupConflictsView.currentPrecs.isActive()) {
// That should not happen, if we are inside a connected conflict, button is disabled
// The user wants to reduce, but reduce affects other conflicts
if(srdetails.reduceAffectsOthers && resolutionOptions.getSelectionIndex() == 2){
cupConflictsView.beginConnectedResolution();
cupConflictsView.addFirstPrecedence(srdetails.reduce,srdetails.shift);
return;
}
// These are the cases where nothing is affected
if(resolutionOptions.getSelectionIndex() == 1) // Shift
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Left);
else if (resolutionOptions.getSelectionIndex() == 2) // Reduce
cupConflictsView.insertSinglePrecedence(srdetails.reduce,Precedence.Type.Left);
}
if(!srdetails.shiftAndReducePrecedenceFromSameTerminal()){
// The user wants to shift, but shifting affects other conflicts
if(srdetails.shiftAffectsOthers && resolutionOptions.getSelectionIndex() == 1){
cupConflictsView.beginConnectedResolution();
cupConflictsView.addFirstPrecedence(srdetails.shift,srdetails.reduce);
return;
}
// The user wants to reduce, but reduce affects other conflicts
if(srdetails.reduceAffectsOthers && resolutionOptions.getSelectionIndex() == 2){
cupConflictsView.beginConnectedResolution();
cupConflictsView.addFirstPrecedence(srdetails.reduce,srdetails.shift);
return;
}
else {
// Checking this is sufficient since the terminals are identical
if(srdetails.shiftAffectsOthers) {
forceEnableDropdown = true;
cupConflictsView.beginConnectedResolution();
// These are the cases where nothing is affected
if(resolutionOptions.getSelectionIndex() == 1) // Shift
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Left);
else if (resolutionOptions.getSelectionIndex() == 2) // Reduce
cupConflictsView.insertSinglePrecedence(srdetails.reduce,Precedence.Type.Left);
}
else {
// Checking this is sufficient since the terminals are identical
if(srdetails.shiftAffectsOthers) {
forceEnableDropdown = true;
cupConflictsView.beginConnectedResolution();
if(resolutionOptions.getSelectionIndex() == 1) { // Shift
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.Right);
}
else if (resolutionOptions.getSelectionIndex() == 2) { // Reduce
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.Left);
}
else if (resolutionOptions.getSelectionIndex() == 3) { // Non-Assoc
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.NonAssoc);
}
}
else if(resolutionOptions.getSelectionIndex() == 1) { // Shift
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Right);
if(resolutionOptions.getSelectionIndex() == 1) { // Shift
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.Right);
}
else if (resolutionOptions.getSelectionIndex() == 2) { // Reduce
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Left);
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.Left);
}
else if (resolutionOptions.getSelectionIndex() == 3) { // Non-Assoc
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.NonAssoc);
cupConflictsView.setTerminalAssoc(srdetails.shift,Precedence.Type.NonAssoc);
}
}
else if(resolutionOptions.getSelectionIndex() == 1) { // Shift
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Right);
}
else if (resolutionOptions.getSelectionIndex() == 2) { // Reduce
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.Left);
}
else if (resolutionOptions.getSelectionIndex() == 3) { // Non-Assoc
cupConflictsView.insertSinglePrecedence(srdetails.shift,Precedence.Type.NonAssoc);
}
}
}
private void resolutionButtonRRClick() throws internal_error, BadLocationException {
ReduceReduceConflict rrc = (ReduceReduceConflict) conflict;
lr_item_core item1 = new lr_item_core(rrc.getConflictItem1().the_production(),rrc.getConflictItem1().dot_pos());
lr_item_core item2 = new lr_item_core(rrc.getConflictItem2().the_production(),rrc.getConflictItem2().dot_pos());
if(!cupConflictsView.settingOrderAffetsOtherConflicts(item1, item2)){
ReduceReduceReorder rrr = new ReduceReduceReorder(cupConflictsView.getDocument(),cupConflictsView.isThresholdPresent());
if(resolutionOptions.getSelectionIndex() ==1){
rrr.moveItemToVeryEnd(rrc.getConflictItem1());
rrr.moveItemToVeryEnd(rrc.getConflictItem2());
}
else if(resolutionOptions.getSelectionIndex() ==2){
rrr.moveItemToVeryEnd(rrc.getConflictItem2());
rrr.moveItemToVeryEnd(rrc.getConflictItem1());
}
rrr.apply();
}
else {
}
}
private SelectionListener resolutionButtonClick = new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e){ }
public void widgetSelected(SelectionEvent e){
if(resolutionOptions.getSelectionIndex() == 0){
return;
}
if(conflict instanceof ShiftReduceConflict){
resolutionButtonSRClick();
}
if(conflict instanceof ReduceReduceConflict) {
try {
resolutionButtonRRClick();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
......
......@@ -64,7 +64,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private static final int OUTER_MARGIN = 10;
static final int INNER_MARGIN = 5;
private static final String TRESHOLD_STRING = "~~ CUP-ECLIPSE:CONFLICT-RES-RR ~~ ";
static final String TRESHOLD_STRING = "~~ CUP-ECLIPSE:CONFLICT-RES-RR ~~ ";
Jumper jumper;
private CupTextEditor editor;
......@@ -79,7 +79,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
private HashMap<lr_item_core,Integer> ordersAffectConflicts;
PrecedenceToInsert currentPrecs;
private int ignoreRRAfterLine;
public int ignoreRRAfterLine;
class ShiftReduceDetails {
terminal shift,reduce;
......@@ -547,6 +547,10 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
boolean isThresholdPresent(){
return (ignoreRRAfterLine != -1);
}
boolean settingOrderAffetsOtherConflicts(lr_item_core item1,lr_item_core item2){
Integer affected = ordersAffectConflicts.get(item1);
......@@ -591,6 +595,9 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
}
}
public IDocument getDocument(){
return editor.getDocument();
}
public void moveItemToVeryEnd(lalr_item item){
Production p =(Production)item.the_production().getAstNode().getParent();
......@@ -612,6 +619,7 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
if(ignoreRRAfterLine == -1){
toInsert = "\n\n// " + TRESHOLD_STRING + "\n // After this the order of productions matters" + toInsert;
ignoreRRAfterLine = 0;
}
document.replace(positionForProd, 0, toInsert);
......
package de.tum.in.www2.cupplugin.views;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.internal.lalr_item;
import de.tum.in.www2.cupplugin.model.Model;
public class ReduceReduceReorder {
IDocument document;
String textToAppend;
boolean flagPresent;
private List<RangeToRemove> rangesToRemove;
private class RangeToRemove implements Comparable<RangeToRemove>{
int start;
int length;
public RangeToRemove(int start,int length){
this.start = start;
this.length = length;
}
@Override
public int compareTo(RangeToRemove o){
return (this.start-o.start);
}
}
public ReduceReduceReorder(IDocument document,boolean flagPresent){
this.document = document;
this.flagPresent = flagPresent;
textToAppend="";
rangesToRemove = new ArrayList<>();
}
public void moveItemToVeryEnd(lalr_item item){
Production p =(Production)item.the_production().getAstNode().getParent();
if(p.getRightHandSides().size() == 1){
// Base case
try {
String pString = document.get(p.getBegin().getOffsetFromStart(),
p.getEnd().getOffsetFromStart() - p.getBegin().getOffsetFromStart());
String toInsert = "\n\n//Moved by CUP Eclipse plugin\n" + pString;
if(!flagPresent){
toInsert = "\n\n// " + CupConflictsView.TRESHOLD_STRING + "\n // After this the order of productions matters" + toInsert;
flagPresent = true;
}
textToAppend += toInsert;
rangesToRemove.add(new RangeToRemove(p.getBegin().getOffsetFromStart(), p.getEnd().getOffsetFromStart() - p.getBegin().getOffsetFromStart()));
return;
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return;
}
public void apply() throws BadLocationException{
insert();
removeAllOldItems();
}
private void insert() throws BadLocationException{
int positionForProd = 0;
ParserResult r = Model.getInstanceForDocument(document).getAstModel();
// Grammar can be assumed to have at least two productions -> safe
positionForProd = r.productions.get(r.productions.size()-1).getEnd().getOffsetFromStart();
document.replace(positionForProd, 0, textToAppend);
}
private void removeAllOldItems() throws BadLocationException{
Collections.sort(rangesToRemove);
Collections.reverse(rangesToRemove);
for(RangeToRemove rtm : rangesToRemove){
document.replace(rtm.start, rtm.length, "");
}
}
}
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