use of org.antlr.analysis.NFAState in project antlrworks by antlr.
the class GFactory method buildGraphGroup.
private GGraphGroup buildGraphGroup(Grammar grammar, GrammarError error) {
// Create one GGraph for each error rules
List<GGraph> graphs = new ArrayList<GGraph>();
FAFactory factory = new FAFactory(grammar);
for (String rule : error.rules) {
NFAState startState = grammar.getRuleStartState(rule);
FAState state = factory.buildNFA(startState, optimize);
GGraph graph = renderer.render(state);
graph.setName(rule);
graphs.add(graph);
}
// Add only graphs that are referenced by at least one error path.
// For example, the statement rule of the java.g grammar produces
// states that do not exist in the graph (they are after the accepted state
// and are ignored by the FAFactory)
GGraphGroup gg = new GGraphGroup();
for (GGraph graph : graphs) {
if (graph.containsAtLeastOneState(error.states))
gg.add(graph);
}
// Attach all error paths to the GGraphGroup
for (int i = 0; i < error.paths.size(); i++) {
List states = error.paths.get(i);
Boolean disabled = error.pathsDisabled.get(i);
try {
gg.addPath(states, disabled, factory.getSkippedStatesMap());
} catch (Exception e) {
if (console == null)
e.printStackTrace();
else
console.println(e);
}
}
// Attach all unreacheable alts to the GGraphGroup
for (Object[] unreachableAlt : error.unreachableAlts) {
gg.addUnreachableAlt((NFAState) unreachableAlt[0], (Integer) unreachableAlt[1]);
}
if (error.paths.size() > 0)
gg.getPathGroup().setPathVisible(0, true);
return gg;
}
use of org.antlr.analysis.NFAState in project antlrworks by antlr.
the class GFactory method buildGraphsForRule.
public GGraph buildGraphsForRule(ANTLRGrammarEngine antlrEngineGrammar, String rule) throws Exception {
NFAState startState = antlrEngineGrammar.getRuleStartState(rule);
if (startState == null)
return null;
FAState state = new FAFactory(antlrEngineGrammar.getGrammarForRule(rule)).buildNFA(startState, optimize);
GGraph graph = renderer.render(state);
graph.setName(rule);
return graph;
}
use of org.antlr.analysis.NFAState in project antlrworks by antlr.
the class GGraphGroup method addPath.
public void addPath(List path, boolean disabled, Map<Integer, FAState> skippedStates) {
List<GPathElement> elements = new ArrayList<GPathElement>();
/** path contains a list of NFAState states (from ANTLR): they represent
* all the states along the path. The graphical representation of the NFA/SD
* does not necessarily contains all the states of the path because the representation
* can be simplified to remove all unecessary states.
* The problem here is to use the information stored in the transition of the
* graphical representation to figure out exactly which graphical node corresponds
* to the path.
*/
NFAState state;
GNode node;
NFAState nextState = null;
GNode nextNode = null;
for (pathIndex = 0; getPathIndex() < path.size(); pathIndex = getPathIndex() + 1) {
if (getPathIndex() == 0) {
nextState = (NFAState) path.get(getPathIndex());
nextNode = findNodeForStateNumber(nextState.stateNumber);
if (nextNode == null) {
// A path can start from anywhere in the graph. It might happen
// that the starting state of the path has been skipped by
// the optimization in FAFactory. We use the skippedStates mapping
// to find out what is the parent state of the skipped state.
FAState parentState = skippedStates.get(nextState.stateNumber);
if (parentState == null) {
System.err.println("[GGraphGroup] Starting path state " + nextState.stateNumber + "[" + nextState.enclosingRule.name + "] cannot be found in the graph");
return;
} else {
nextNode = findNodeForStateNumber(parentState.stateNumber);
}
}
continue;
} else {
state = nextState;
node = nextNode;
}
nextState = (NFAState) path.get(getPathIndex());
nextNode = findNodeForStateNumber(nextState.stateNumber);
GNode externalNode = null;
if (nextNode == null) {
// The state has probably been skipped during the graphical rendering.
// Find the next non-skipped state.
FATransition t = getNodeTransitionToNextNonSkippedState(node, path);
if (t == null) {
// No transition found. Look in the skipped states mapping because
// it might be possible that the next state is in another rule but
// cannot be found because it has been skipped.
FAState parentState = skippedStates.get(nextState.stateNumber);
if (parentState == null) {
// OK. The node really does not exist. Continue by skipping it.
nextNode = node;
continue;
} else {
nextNode = findNodeForStateNumber(parentState.stateNumber);
}
} else {
// is incrementing it
if (getPathIndex() >= path.size()) {
nextNode = findNodeForStateNumber(t.target.stateNumber);
} else {
nextState = (NFAState) path.get(getPathIndex());
if (t.target.stateNumber == nextState.stateNumber) {
nextNode = findNodeForStateNumber(t.target.stateNumber);
} else {
// The only case that the target state of the transition if not
// the next state of the path is when the next state of the path
// is in another rule. In this case, the target state of the transition
// will contain a negative state number indicating an external rule reference:
// this external rule reference is added by AW during rendering and is not
// part of any ANTLR NFA.
// This node is the node representing the external rule reference
// before jumping outside of the rule
externalNode = findNodeForStateNumber(t.target.stateNumber);
// This node is the first node in the other rule
nextNode = findNodeForStateNumber(nextState.stateNumber);
}
}
}
}
if (state == null || node == null || nextNode == null)
continue;
if (state.enclosingRule.name.equals(nextState.enclosingRule.name))
addNextElementInSameRule(elements, node, nextNode);
else
addNextElementInOtherRule(elements, node, externalNode, nextNode, nextState);
}
if (nextNode != null)
elements.add(GPathElement.createElement(nextNode));
getPathGroup().addPath(new GPath(elements, disabled));
}
use of org.antlr.analysis.NFAState 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.analysis.NFAState 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;
}
Aggregations