Commit 1f23a380 authored by Johannes Roith's avatar Johannes Roith

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

parents 1590c752 2949f6fd
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> allInterestingConflicts;
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) {
allInterestingConflicts = 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;
allInterestingConflicts.clear();
stateHashMap.clear();
searchStack.clear();
visitedStates.clear();
dijkstraResult.clear();
sharedState = lalr_state.getShared(lalrContext);
for (Conflict conf : lalrContext.getConflictManager().getConflicts()) {
if (conf instanceof ShiftReduceConflict
|| conf instanceof ReduceReduceConflict) {
allInterestingConflicts.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> getAllInterstingConflicts() {
return allInterestingConflicts;
}
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;
int counter = 0;
DFSNode actualNode = searchStack.pop();
while (actualNode != null) {
if (oldConflictState == null) {
oldConflictState = new CupConflictState(
actualNode.getState(), null);
oldDFSNode = actualNode;
resultList.add(oldConflictState);
actualNode = searchStack.pop();
continue;
}
CupConflictState predecessor = new CupConflictState(
actualNode.getState(),
oldDFSNode.getPredTransition());
predecessor.setSuccessor(oldConflictState);
oldConflictState = predecessor;
if(!searchStack.isEmpty()) {
actualNode = searchStack.pop();
} else {
actualNode = null;
}
}
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;
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;
}
}
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