use of org.antlr.works.visualization.fa.FATransition in project antlrworks by antlr.
the class GGraphGroup method addNextElementInSameRule.
public void addNextElementInSameRule(List<GPathElement> elements, GNode node, GNode nextNode) {
elements.add(GPathElement.createElement(node));
// Use nextNode instead of nextState (previously in parameter) because nextState
// could be null if it was skipped during optimization. nextNode cannot be null.
FATransition t = node.state.getTransitionToStateNumber(nextNode.state.stateNumber);
if (t == null) {
// Probably a loop. In this case, the transition is located in the target state.
t = nextNode.state.getTransitionToStateNumber(node.state.stateNumber);
if (t == null) {
// Still no transition found. This is a reference to the same rule (recursive)
elements.add(GPathElement.createLink(node, nextNode));
} else {
// Add the loop transition to the path
elements.add(GPathElement.createElement(nextNode.getLink(t)));
}
} else {
// Add the transition to the path
elements.add(GPathElement.createElement(node.getLink(t)));
}
}
use of org.antlr.works.visualization.fa.FATransition in project antlrworks by antlr.
the class GGraphGroup method getNodeTransitionToNextNonSkippedState.
public FATransition getNodeTransitionToNextNonSkippedState(GNode node, List path) {
if (node == null)
return null;
List<FATransition> candidateTransitions = new ArrayList<FATransition>(node.state.transitions);
FATransition candidate = null;
int start = getPathIndex();
loop: for (; getPathIndex() < path.size(); pathIndex = getPathIndex() + 1) {
candidateTransitions = getTransitionsMatchingSkippedStates(candidateTransitions, path.subList(start, getPathIndex() + 1));
switch(candidateTransitions.size()) {
case // No more transitions. Exit and use the candidate transition.
0:
break loop;
case 1:
// The uniquely identified transition has been found.
// Continue to loop until all skipped states have been found.
candidate = candidateTransitions.get(0);
break;
default:
// the others (the next state of the path can return no transition at all)
if (getPathIndex() + 1 < path.size()) {
NFAState nextPathState = (NFAState) path.get(getPathIndex() + 1);
for (FATransition t : candidateTransitions) {
if (t.target.stateNumber == nextPathState.stateNumber) {
// always points to the next element after the transition
pathIndex = getPathIndex() + 1;
return t;
}
}
}
break;
}
}
return candidate;
}
use of org.antlr.works.visualization.fa.FATransition in project antlrworks by antlr.
the class GGraphGroup method getTransitionsMatchingSkippedStates.
public List<FATransition> getTransitionsMatchingSkippedStates(List<FATransition> candidates, List states) {
/** First convert the list of NFAStates to a list of Integer containing
* the state number
*/
List<Integer> statesNumbers = new ArrayList<Integer>();
for (Object state : states) {
statesNumbers.add((((NFAState) state).stateNumber));
}
/** Select only the transitions that containing all the state numbers */
List<FATransition> newCandidates = new ArrayList<FATransition>();
for (FATransition t : candidates) {
if (t.skippedStates != null && t.skippedStates.containsAll(statesNumbers)) {
newCandidates.add(t);
}
}
return newCandidates;
}
use of org.antlr.works.visualization.fa.FATransition in project antlrworks by antlr.
the class GGraphGroup method addUnreachableAlt.
public void addUnreachableAlt(NFAState state, Integer alt) {
List<GPathElement> elements = new ArrayList<GPathElement>();
GNode node = findNodeForStateNumber(state.stateNumber);
if (node == null) {
System.err.println("[GGraphGroup] Decision state " + state.stateNumber + "[" + state.enclosingRule.name + "] cannot be found in the graph");
return;
}
List<FATransition> transitions = node.state.transitions;
int altNum = alt - 1;
if (altNum >= transitions.size()) {
System.err.println("[GGraphGroup] Unreachable alt " + altNum + "[" + state.enclosingRule.name + "] is out of bounds: " + transitions.size());
return;
}
FATransition t = transitions.get(altNum);
elements.add(GPathElement.createElement(node));
elements.add(GPathElement.createElement(node.getLink(t)));
/** This path has to be visible but not selectable */
GPath path = new GPath(elements, true);
path.setVisible(true);
path.setSelectable(false);
getPathGroup().addPath(path);
}
use of org.antlr.works.visualization.fa.FATransition in project antlrworks by antlr.
the class GRenderer method recursiveRenderSizeAlternative.
public GDimension recursiveRenderSizeAlternative(FAState state) {
FAState alternativeEndState = alternativeEndState(state);
GNode norigin = createNode(state);
GDimension dimension = norigin.linkDimension;
dimension.addWidth(GContext.EPSILON_WIDTH);
GDimension firstTransitionDimension = null;
for (int t = 0; t < state.getNumberOfTransitions(); t++) {
FATransition transition = state.transition(t);
GLink link = new GLink();
link.transition = transition;
link.target = createNode(transition.target);
norigin.addLink(link);
boolean last = t == state.getNumberOfTransitions() - 1;
if (t == state.getNumberOfTransitions() - 2 && state.transition(t + 1).loop) {
// If the last alternative is a loop, consider the last-1 alternative as the last one:
// the loop will be displayed above the first transition (up) in order to see it easily
// from the other transition(s).
last = true;
}
link.setLast(last);
if (transition.target == alternativeEndState) {
GDimension transitionDimension = new GDimension();
transitionDimension.addUp(GContext.EPSILON_UP);
transitionDimension.addDown(GContext.EPSILON_DOWN);
if (transition.loop)
transitionDimension.addDown(GContext.LINE_SPACE);
if (transition.loop) {
link.setBranchDimension(transitionDimension);
dimension.maxUp(firstTransitionDimension.up + transitionDimension.up + transitionDimension.down);
} else {
link.setBranchDimension(transitionDimension);
if (t == 0) {
firstTransitionDimension = transitionDimension;
}
dimension.addDown(transitionDimension.up);
dimension.addDown(transitionDimension.down);
}
} else {
endOfAlternativeInfoMap.put(alternativeEndState, new EOAInfo(last));
GDimension transitionDimension = recursiveRenderSizeSingle(transition.target, alternativeEndState);
if (((t > 0) || (t == 0 && !state.transition(1).loop)) && !last)
dimension.addDown(GContext.LINE_SPACE);
link.setBranchDimension(transitionDimension);
transitionDimension.addWidth(GContext.EPSILON_WIDTH);
dimension.maxWidth(transitionDimension.width);
if (t == 0) {
// Remember the size of the first transition
firstTransitionDimension = transitionDimension;
// Add its "up" size to the transition "up" size
dimension.maxUp(transitionDimension.up);
dimension.addDown(transitionDimension.down);
} else {
dimension.addDown(transitionDimension.up);
dimension.addDown(transitionDimension.down);
}
}
}
return dimension;
}
Aggregations