Commit 993ca8ec authored by Benedikt Engeser's avatar Benedikt Engeser

Merge branch 'master' of git@github.com:jroith/cup-eclipse.git

parents 4faabc85 942ab083
......@@ -5,21 +5,21 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/CupAntBasedBuilder.launch</value>
<value>&lt;project&gt;/.externalToolBuilders/New_Builder.launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
......
......@@ -94,6 +94,7 @@ import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
import java.util.Hashtable;
import java.util.Stack;
import java.util.List;
import java.util.LinkedList;
import java.util.ArrayList;
import de.in.tum.www2.cup.*;
import de.in.tum.www2.cup.ast.*;
......@@ -241,7 +242,10 @@ parser code {:
}
/* override error routines */
protected Lexer lexer;
@Override
public void report_fatal_error(
String message,
Object info)
......@@ -254,6 +258,7 @@ parser code {:
throw new ParserAbortException();
}
@Override
public void report_error(String message, Object info)
{
if (info instanceof Symbol)
......@@ -261,6 +266,16 @@ parser code {:
else
errMan.Error(ErrorSource.Parser, message, (ComplexSymbol) cur_token);
}
@Override
protected void report_expected_token_ids() {
List<Integer> ids = expected_token_ids();
LinkedList<String> list = new LinkedList<String>();
for (Integer expected : ids)
list.add(symbl_name_from_id(expected));
String msg = "instead expected token classes are " + list;
errMan.Error(ErrorSource.Parser, msg);
}
:};
/*---------------------------------------------------------------- */
......
......@@ -10,6 +10,8 @@ public abstract class Conflict
public lalr_state getState() {
return state;
}
public abstract ConflictType getType();
public Conflict(lalr_state state) {
this.state = state;
......
package de.in.tum.www2.cup;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import de.in.tum.www2.cup.ConflictResolutionManager.DijkstraNode;
import de.in.tum.www2.cup.internal.lalr_state;
import de.in.tum.www2.cup.internal.lalr_transition;
public class ConflictResolutionManager {
private boolean useDijkstar;
private CupContext lalrContext;
private lalr_state.lalr_state_shared sharedState;
private final List<Conflict> allConflicts;
private final HashMap<Integer, lalr_state> stateHashMap;
private final Stack<DFSNode> searchStack;
private final HashSet<lalr_state> visitedStates;
private final HashMap<Integer, DijkstraNode> dijkstraResult;
public ConflictResolutionManager(CupContext lalrContext) {
this(lalrContext, true);
}
public ConflictResolutionManager(CupContext lalrContext, boolean useDijkstra) {
allConflicts = new LinkedList<Conflict>();
stateHashMap = new HashMap<Integer, lalr_state>();
searchStack = new Stack<DFSNode>();
visitedStates = new HashSet<lalr_state>();
dijkstraResult = new HashMap<Integer, DijkstraNode>();
this.useDijkstar = useDijkstra;
this.setLaLrContext(lalrContext);
}
public void setLaLrContext(CupContext lalrContext) {
if(lalrContext==null) {
this.lalrContext = null;
return;
}
this.lalrContext = lalrContext;
allConflicts.clear();
stateHashMap.clear();
searchStack.clear();
visitedStates.clear();
dijkstraResult.clear();
sharedState = lalr_state.getShared(lalrContext);
for (Conflict conf : lalrContext.getConflictManager().getConflicts()) {
allConflicts.add(conf);
}
Enumeration allEnum = sharedState.all();
while (allEnum.hasMoreElements()) {
Object o = allEnum.nextElement();
if (o instanceof lalr_state) {
stateHashMap.put(((lalr_state) o).index(), (lalr_state) o);
}
}
}
public boolean isUseDijkstar() {
return useDijkstar;
}
public void setUseDijkstar(boolean useDijkstar) {
this.useDijkstar = useDijkstar;
}
public List<Conflict> getAllConflicts() {
return allConflicts;
}
private HashMap<Integer, DijkstraNode> dijkstraSearch() {
List<DijkstraNode> searchSet = new LinkedList<DijkstraNode>();
HashMap<Integer, DijkstraNode> dijkstraHashMap = new HashMap<Integer, DijkstraNode>();
for (Map.Entry<Integer, lalr_state> entry : stateHashMap.entrySet()) {
lalr_state state = entry.getValue();
DijkstraNode n = new DijkstraNode(state);
if (entry.getKey() == 0) {
n.distanceToRoot = 0;
}
dijkstraHashMap.put(entry.getKey(), n);
searchSet.add(n);
}
Collections.sort(searchSet);
while (!searchSet.isEmpty()) {
DijkstraNode n = searchSet.get(0);
searchSet.remove(0);
lalr_transition trans = n.getState().transitions();
while (trans != null) {
DijkstraNode connectedNode = dijkstraHashMap.get(trans
.to_state().index());
int dist = 0;
if (trans.on_symbol().is_non_term()) {
dist = dijkstraHashMap.size();
}
dist += n.getDistanceToRoot() + 1;
if (connectedNode.getDistanceToRoot() == -1
|| connectedNode.getDistanceToRoot() > dist) {
connectedNode.setDistanceToRoot(dist);
connectedNode.setPredecessorTransition(trans);
connectedNode.setOptimalPredecessor(n);
}
trans = trans.next();
}
Collections.sort(searchSet);
}
return dijkstraHashMap;
}
private boolean doDFSSearch(DFSNode state, int searchIndex) {
if (state.getState().index() == searchIndex) {
// TODO: Want to only end with nonTerminals?
/*
* if(state.predecessor != null &&
* !state.predTransition.on_symbol().is_non_term()) { return true; }
* return false;
*/
return true;
}
visitedStates.add(state.getState());
lalr_transition trans = state.getState().transitions();
// System.out.println("Trans Symbol is non term: "+trans.on_symbol().is_non_term());
while (trans != null) {
if (visitedStates.contains(trans.to_state())
|| trans.on_symbol().is_non_term()) {
trans = trans.next();
continue;
} else {
DFSNode node = new DFSNode(trans.to_state(), state.getState(),
trans);
searchStack.push(node);
if (doDFSSearch(node, searchIndex)) {
return true;
}
searchStack.pop();
}
trans = trans.next();
}
trans = state.getState().transitions();
while (trans != null) {
if (visitedStates.contains(trans.to_state())
|| !trans.on_symbol().is_non_term()) {
trans = trans.next();
continue;
} else {
DFSNode node = new DFSNode(trans.to_state(), state.getState(),
trans);
searchStack.push(node);
if (doDFSSearch(node, searchIndex)) {
return true;
}
searchStack.pop();
}
trans = trans.next();
}
return false;
}
public List<CupConflictState> searchForState(lalr_state stateToFind) {
if (useDijkstar) {
if(dijkstraResult.isEmpty()) {
HashMap<Integer, DijkstraNode> result = dijkstraSearch();
if (result == null) {
return null;
}
dijkstraResult.putAll(result);
}
DijkstraNode foundNode = dijkstraResult.get(stateToFind.index());
if (foundNode == null) {
return null;
}
List<CupConflictState> resultList = new LinkedList<CupConflictState>();
CupConflictState oldState = new CupConflictState(
foundNode.getState(), null);
resultList.add(oldState);
while (foundNode.getOptimalPredecessor() != null) {
DijkstraNode predecesor = foundNode.getOptimalPredecessor();
CupConflictState predecessorState = new CupConflictState(
predecesor.getState(),
foundNode.getPredecessorTransition());
predecessorState.setSuccessor(oldState);
resultList.add(predecessorState);
oldState = predecessorState;
foundNode = predecesor;
}
Collections.reverse(resultList);
return resultList;
} else {
searchStack.clear();
visitedStates.clear();
DFSNode startNode = new DFSNode(stateHashMap.get(0), null, null);
searchStack.push(startNode);
if (doDFSSearch(startNode, stateToFind.index())) {
List<CupConflictState> resultList = new LinkedList<CupConflictState>();
CupConflictState oldConflictState = null;
DFSNode oldDFSNode = null;
DFSNode actualNode = searchStack.pop();
while (actualNode != null) {
if(oldConflictState==null) {
oldConflictState = new CupConflictState(actualNode.state, null);
oldDFSNode = actualNode;
resultList.add(oldConflictState);
if(!searchStack.isEmpty()) {
actualNode = searchStack.pop();
} else {
actualNode = null;
}
continue;
}
CupConflictState newConflictState = new CupConflictState(actualNode.getState(), oldDFSNode.getPredTransition());
newConflictState.setSuccessor(oldConflictState);
resultList.add(newConflictState);
oldConflictState = newConflictState;
oldDFSNode = actualNode;
if(!searchStack.isEmpty()) {
actualNode = searchStack.pop();
} else {
actualNode = null;
}
}
Collections.reverse(resultList);
return resultList;
} else {
return null;
}
}
}
static class DijkstraNode implements Comparable<DijkstraNode> {
private final lalr_state state;
private int distanceToRoot;
private DijkstraNode optimalPredecessor;
private lalr_transition predecessorTransition;
public DijkstraNode(lalr_state state) {
this.state = state;
distanceToRoot = -1;
optimalPredecessor = null;
predecessorTransition = null;
}
public lalr_state getState() {
return state;
}
public int getDistanceToRoot() {
return distanceToRoot;
}
public void setDistanceToRoot(int distanceToRoot) {
this.distanceToRoot = distanceToRoot;
}
public DijkstraNode getOptimalPredecessor() {
return optimalPredecessor;
}
public void setOptimalPredecessor(DijkstraNode optimalPredecessor) {
this.optimalPredecessor = optimalPredecessor;
}
public lalr_transition getPredecessorTransition() {
return predecessorTransition;
}
public void setPredecessorTransition(
lalr_transition predecessorTransition) {
this.predecessorTransition = predecessorTransition;
}
@Override
public int compareTo(DijkstraNode o) {
if (this.distanceToRoot == o.getDistanceToRoot()) {
return 0;
} else if (this.distanceToRoot == -1) {
return 1;
} else if (o.distanceToRoot == -1) {
return -1;
} else {
return this.distanceToRoot - o.distanceToRoot;
}
}
}
static class DFSNode {
private lalr_state state;
private lalr_state predecessor;
private lalr_transition predTransition;
public DFSNode(lalr_state state, lalr_state predecessor,
lalr_transition predTransition) {
this.state = state;
this.predecessor = predecessor;
this.predTransition = predTransition;
}
public lalr_state getState() {
return state;
}
public void setState(lalr_state state) {
this.state = state;
}
public lalr_state getPredecessor() {
return predecessor;
}
public void setPredecessor(lalr_state predecessor) {
this.predecessor = predecessor;
}
public lalr_transition getPredTransition() {
return predTransition;
}
public void setPredTransition(lalr_transition predTransition) {
this.predTransition = predTransition;
}
}
}
package de.in.tum.www2.cup;
public enum ConflictType {
ShiftReduce,
ReduceReduce
}
package de.in.tum.www2.cup;
import de.in.tum.www2.cup.internal.lalr_state;
import de.in.tum.www2.cup.internal.lalr_transition;
public class CupConflictState {
private final lalr_state state;
private final lalr_transition transition;
private CupConflictState successor;
public CupConflictState(lalr_state state, lalr_transition transition) {
this.state = state;
this.transition = transition;
this.successor = null;
}
public CupConflictState getSuccessor() {
return successor;
}
public void setSuccessor(CupConflictState successor) {
this.successor = successor;
}
public lalr_state getState() {
return state;
}
public lalr_transition getTransition() {
return transition;
}
}
......@@ -128,6 +128,26 @@ public class CupSymbol {
}
}
public static boolean isDelimiter(char c) {
switch (c) {
case ' ':
case '\t':
case '?':
case ';':
case ',':
case '*':
case '.':
case '|':
case '[':
case ']':
case ':':
case '<':
case '>':
return true;
}
return false;
}
public static String[] getKeywords() {
return keywordStrings;
}
......
......@@ -100,6 +100,10 @@ public class ErrorManager
Error(ErrorSource.Unknown, msg, null, null);
}
public void Error(ErrorSource source, String msg) {
Error(source, msg, null, null);
}
public void Error(ErrorSource source, String msg, Position start) {
Error(source, msg, start, null);
}
......
......@@ -25,6 +25,11 @@ public class ReduceReduceConflict extends Conflict
return conflict2;
}
@Override
public ConflictType getType() {
return ConflictType.ReduceReduce;
}
public ReduceReduceConflict(lalr_state state, lalr_item conflict1, lalr_item conflict2, List<terminal> terminals) {
super(state);
this.conflict1 = conflict1;
......
......@@ -24,6 +24,11 @@ public class ShiftReduceConflict extends Conflict
return conflict2;
}
@Override
public ConflictType getType() {
return ConflictType.ShiftReduce;
}
public ShiftReduceConflict(lalr_state state, lalr_item conflict1, List<lalr_item> conflict2, terminal terminal) {
super(state);
this.conflict1 = conflict1;
......
......@@ -3,8 +3,10 @@ package de.tum.in.www2.cupplugin.editors;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import de.in.tum.www2.cup.ConflictType;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
import de.tum.in.www2.cupplugin.PluginUtility;
public class Jumper {
......@@ -13,6 +15,14 @@ public class Jumper {
Jumper (MultiPageEditor mpe) {
this.mpe = mpe;
}
public void jumpToConflictGraphState(ConflictType conflictType, int index) {
//PluginUtility.showMessage("Jumper: Jump to conflict graph state - not yet implemented!");
mpe.jumpTo(mpe.CONFLICT_GRAPH_PAGE_INDEX);
// TODO!
mpe.getConflictGraphView().showConflict(conflictType, index);
}
public void jumpToEditorSelection(Range range) {
if (range == null)
......
......@@ -63,6 +63,10 @@ public class MultiPageEditor extends MultiPageEditorPart implements
return editor;
}
CupConflictGraphView getConflictGraphView() {
return conflictGraphView;
}
void createEditorPage(Jumper jumper) {
try {
editor = new CupTextEditor(jumper);
......
......@@ -24,6 +24,7 @@ import org.eclipse.ui.forms.widgets.TableWrapLayout;
import de.in.tum.www2.cup.Conflict;
import de.in.tum.www2.cup.ConflictManager;
import de.in.tum.www2.cup.ConflictType;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.ReduceReduceConflict;
......@@ -57,6 +58,11 @@ public class CupConflictsView implements ICupEditorPageVisibility,
class ConflictPanel extends Composite {
private static final int COLUMNS = 3;
private static final int HEADING_FONT_SIZE = 14;
private Conflict conflict;
private Label conflictTypeLabel;
private Link stateLabel;
private Label symbolLabel;
......@@ -83,34 +89,37 @@ public class CupConflictsView implements ICupEditorPageVisibility,
data.heightHint = 80;
setLayoutData(data);
TableWrapLayout layout = new TableWrapLayout();
layout.numColumns = 3;
layout.verticalSpacing = 8;
setLayout(layout);
GridLayout gl = new GridLayout();
gl.numColumns = COLUMNS;
gl.makeColumnsEqualWidth = false;
setLayout(gl);
this.conflictTypeLabel = new Label(this, SWT.NONE);
FontData[] fD = conflictTypeLabel.getFont().getFontData();
fD[0].setHeight(14);
fD[0].setHeight(HEADING_FONT_SIZE);
conflictTypeLabel.setFont( new Font(Display.getCurrent(),fD[0]));
this.symbolLabel = new Label(this, SWT.NONE);
this.stateLabel = new Link(this, SWT.NONE);
GridData td2 = new GridData(GridData.HORIZONTAL_ALIGN_END);
td2.grabExcessHorizontalSpace = true;
td2.widthHint = 60;
stateLabel.setLayoutData(td2);
stateLabel.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
PluginUtility.showMessage("Not yet implemented!");
if (conflict == null)
return;
jumper.jumpToConflictGraphState(conflict.getType(), Integer
.parseInt(e.text));
}
});
this.detailText = new Link(this, SWT.WRAP);
this.detailText.setBackground(new Color(Display.getCurrent(),
Colors.lightGray));
TableWrapData td = new TableWrapData();
td.colspan = 1;
detailText.setLayoutData(td);
Composite detailWrapper = makeDetailWrapper(COLUMNS);
this.detailText = new Link(detailWrapper, SWT.WRAP);
detailText.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
......@@ -121,6 +130,26 @@ public class CupConflictsView implements ICupEditorPageVisibility,
});
}
private Composite makeDetailWrapper(int columns) {
Composite detailWrapper = new Composite(this, SWT.WRAP);
detailWrapper.setBackground(new Color(Display.getCurrent(), Colors.red));
GridData detailTextData = new GridData();
detailTextData.grabExcessHorizontalSpace = true;
detailTextData.horizontalSpan = columns;
detailWrapper.setLayoutData(detailTextData);
TableWrapLayout layout = new TableWrapLayout();
layout.bottomMargin = 0;
layout.topMargin = 0;
layout.leftMargin = 0;
layout.rightMargin = 0;
layout.makeColumnsEqualWidth = false;
layout.numColumns = 1;
layout.verticalSpacing = 0;
detailWrapper.setLayout(layout);
return detailWrapper;
}
private void changeColors(Color background, Color foreground) {
setBackground(background);
detailText.setBackground(background);
......@@ -132,10 +161,13 @@ public class CupConflictsView implements ICupEditorPageVisibility,
}
public void update(Conflict conflict) {
this.conflict = conflict;
links.clear();
int linkCounter = 0;
stateLabel.setText("<a href=\"TODO\">State: " + conflict.getState().index() + "</a>");
int cindex = conflict.getState().index();
stateLabel.setText("<a href=\"" + cindex + "\">State: " + cindex + "</a>");
if (conflict instanceof ReduceReduceConflict) {
ReduceReduceConflict rrc = (ReduceReduceConflict) conflict;
......@@ -300,10 +332,7 @@ public class CupConflictsView implements ICupEditorPageVisibility,
conflictPanels.add(new ConflictPanel(list, SWT.NONE));
}
}
System.out
.println("conflictPanels size: " + this.conflictPanels.size());
System.out.println("conflictPanels size: " + this.conflictPanels.size());
}