use of org.antlr.v4.runtime.atn.NotSetTransition in project antlr4 by antlr.
the class DOTGenerator method getDOT.
/**
* Return a String containing a DOT description that, when displayed,
* will show the incoming state machine visually. All nodes reachable
* from startState will be included.
*/
public String getDOT(ATNState startState, String[] ruleNames, boolean isLexer) {
if (startState == null)
return null;
// The output DOT graph for visualization
Set<ATNState> markedStates = new HashSet<ATNState>();
ST dot = stlib.getInstanceOf("atn");
dot.add("startState", startState.stateNumber);
dot.add("rankdir", rankdir);
List<ATNState> work = new LinkedList<ATNState>();
work.add(startState);
while (!work.isEmpty()) {
ATNState s = work.get(0);
if (markedStates.contains(s)) {
work.remove(0);
continue;
}
markedStates.add(s);
// don't go past end of rule node to the follow states
if (s instanceof RuleStopState)
continue;
// special case: if decision point, then line up the alt start states
// unless it's an end of block
// if ( s instanceof BlockStartState ) {
// ST rankST = stlib.getInstanceOf("decision-rank");
// DecisionState alt = (DecisionState)s;
// for (int i=0; i<alt.getNumberOfTransitions(); i++) {
// ATNState target = alt.transition(i).target;
// if ( target!=null ) {
// rankST.add("states", target.stateNumber);
// }
// }
// dot.add("decisionRanks", rankST);
// }
// make a DOT edge for each transition
ST edgeST;
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition edge = s.transition(i);
if (edge instanceof RuleTransition) {
RuleTransition rr = ((RuleTransition) edge);
// don't jump to other rules, but display edge to follow node
edgeST = stlib.getInstanceOf("edge");
String label = "<" + ruleNames[rr.ruleIndex];
if (((RuleStartState) rr.target).isLeftRecursiveRule) {
label += "[" + rr.precedence + "]";
}
label += ">";
edgeST.add("label", label);
edgeST.add("src", "s" + s.stateNumber);
edgeST.add("target", "s" + rr.followState.stateNumber);
edgeST.add("arrowhead", arrowhead);
dot.add("edges", edgeST);
work.add(rr.followState);
continue;
}
if (edge instanceof ActionTransition) {
edgeST = stlib.getInstanceOf("action-edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
} else if (edge instanceof AbstractPredicateTransition) {
edgeST = stlib.getInstanceOf("edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
} else if (edge.isEpsilon()) {
edgeST = stlib.getInstanceOf("epsilon-edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
boolean loopback = false;
if (edge.target instanceof PlusBlockStartState) {
loopback = s.equals(((PlusBlockStartState) edge.target).loopBackState);
} else if (edge.target instanceof StarLoopEntryState) {
loopback = s.equals(((StarLoopEntryState) edge.target).loopBackState);
}
edgeST.add("loopback", loopback);
} else if (edge instanceof AtomTransition) {
edgeST = stlib.getInstanceOf("edge");
AtomTransition atom = (AtomTransition) edge;
String label = String.valueOf(atom.label);
if (isLexer)
label = "'" + getEdgeLabel(new StringBuilder().appendCodePoint(atom.label).toString()) + "'";
else if (grammar != null)
label = grammar.getTokenDisplayName(atom.label);
edgeST.add("label", getEdgeLabel(label));
} else if (edge instanceof SetTransition) {
edgeST = stlib.getInstanceOf("edge");
SetTransition set = (SetTransition) edge;
String label = set.label().toString();
if (isLexer)
label = set.label().toString(true);
else if (grammar != null)
label = set.label().toString(grammar.getVocabulary());
if (edge instanceof NotSetTransition)
label = "~" + label;
edgeST.add("label", getEdgeLabel(label));
} else if (edge instanceof RangeTransition) {
edgeST = stlib.getInstanceOf("edge");
RangeTransition range = (RangeTransition) edge;
String label = range.label().toString();
if (isLexer)
label = range.toString();
else if (grammar != null)
label = range.label().toString(grammar.getVocabulary());
edgeST.add("label", getEdgeLabel(label));
} else {
edgeST = stlib.getInstanceOf("edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
}
edgeST.add("src", "s" + s.stateNumber);
edgeST.add("target", "s" + edge.target.stateNumber);
edgeST.add("arrowhead", arrowhead);
if (s.getNumberOfTransitions() > 1) {
edgeST.add("transitionIndex", i);
} else {
edgeST.add("transitionIndex", false);
}
dot.add("edges", edgeST);
work.add(edge.target);
}
}
// }
for (ATNState s : markedStates) {
if (!(s instanceof RuleStopState))
continue;
ST st = stlib.getInstanceOf("stopstate");
st.add("name", "s" + s.stateNumber);
st.add("label", getStateLabel(s));
dot.add("states", st);
}
for (ATNState s : markedStates) {
if (s instanceof RuleStopState)
continue;
ST st = stlib.getInstanceOf("state");
st.add("name", "s" + s.stateNumber);
st.add("label", getStateLabel(s));
st.add("transitions", s.getTransitions());
dot.add("states", st);
}
return dot.render();
}
use of org.antlr.v4.runtime.atn.NotSetTransition in project antlr4 by tunnelvisionlabs.
the class DOTGenerator method getDOT.
/**
* Return a String containing a DOT description that, when displayed,
* will show the incoming state machine visually. All nodes reachable
* from startState will be included.
*/
public String getDOT(ATNState startState, String[] ruleNames, boolean isLexer) {
if (startState == null)
return null;
// The output DOT graph for visualization
Set<ATNState> markedStates = new HashSet<ATNState>();
ST dot = stlib.getInstanceOf("atn");
dot.add("startState", startState.stateNumber);
dot.add("rankdir", rankdir);
List<ATNState> work = new LinkedList<ATNState>();
work.add(startState);
while (!work.isEmpty()) {
ATNState s = work.get(0);
if (markedStates.contains(s)) {
work.remove(0);
continue;
}
markedStates.add(s);
// don't go past end of rule node to the follow states
if (s instanceof RuleStopState)
continue;
// special case: if decision point, then line up the alt start states
// unless it's an end of block
// if ( s instanceof BlockStartState ) {
// ST rankST = stlib.getInstanceOf("decision-rank");
// DecisionState alt = (DecisionState)s;
// for (int i=0; i<alt.getNumberOfTransitions(); i++) {
// ATNState target = alt.transition(i).target;
// if ( target!=null ) {
// rankST.add("states", target.stateNumber);
// }
// }
// dot.add("decisionRanks", rankST);
// }
// make a DOT edge for each transition
ST edgeST;
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition edge = s.transition(i);
if (edge instanceof RuleTransition) {
RuleTransition rr = ((RuleTransition) edge);
// don't jump to other rules, but display edge to follow node
edgeST = stlib.getInstanceOf("edge");
String label = "<" + ruleNames[rr.ruleIndex];
if (((RuleStartState) rr.target).isPrecedenceRule) {
label += "[" + rr.precedence + "]";
}
label += ">";
edgeST.add("label", label);
edgeST.add("src", "s" + s.stateNumber);
edgeST.add("target", "s" + rr.followState.stateNumber);
edgeST.add("arrowhead", arrowhead);
dot.add("edges", edgeST);
work.add(rr.followState);
continue;
}
if (edge instanceof ActionTransition) {
edgeST = stlib.getInstanceOf("action-edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
} else if (edge instanceof AbstractPredicateTransition) {
edgeST = stlib.getInstanceOf("edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
} else if (edge.isEpsilon()) {
edgeST = stlib.getInstanceOf("epsilon-edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
boolean loopback = false;
if (edge.target instanceof PlusBlockStartState) {
loopback = s.equals(((PlusBlockStartState) edge.target).loopBackState);
} else if (edge.target instanceof StarLoopEntryState) {
loopback = s.equals(((StarLoopEntryState) edge.target).loopBackState);
}
edgeST.add("loopback", loopback);
} else if (edge instanceof AtomTransition) {
edgeST = stlib.getInstanceOf("edge");
AtomTransition atom = (AtomTransition) edge;
String label = String.valueOf(atom.label);
if (isLexer)
label = "'" + getEdgeLabel(new StringBuilder().appendCodePoint(atom.label).toString()) + "'";
else if (grammar != null)
label = grammar.getTokenDisplayName(atom.label);
edgeST.add("label", getEdgeLabel(label));
} else if (edge instanceof SetTransition) {
edgeST = stlib.getInstanceOf("edge");
SetTransition set = (SetTransition) edge;
String label = set.label().toString();
if (isLexer)
label = set.label().toString(true);
else if (grammar != null)
label = set.label().toString(grammar.getVocabulary());
if (edge instanceof NotSetTransition)
label = "~" + label;
edgeST.add("label", getEdgeLabel(label));
} else if (edge instanceof RangeTransition) {
edgeST = stlib.getInstanceOf("edge");
RangeTransition range = (RangeTransition) edge;
String label = range.label().toString();
if (isLexer)
label = range.toString();
else if (grammar != null)
label = range.label().toString(grammar.getVocabulary());
edgeST.add("label", getEdgeLabel(label));
} else {
edgeST = stlib.getInstanceOf("edge");
edgeST.add("label", getEdgeLabel(edge.toString()));
}
edgeST.add("src", "s" + s.stateNumber);
edgeST.add("target", "s" + edge.target.stateNumber);
edgeST.add("arrowhead", arrowhead);
if (s.getNumberOfTransitions() > 1) {
edgeST.add("transitionIndex", i);
} else {
edgeST.add("transitionIndex", false);
}
dot.add("edges", edgeST);
work.add(edge.target);
}
}
// }
for (ATNState s : markedStates) {
if (!(s instanceof RuleStopState))
continue;
ST st = stlib.getInstanceOf("stopstate");
st.add("name", "s" + s.stateNumber);
st.add("label", getStateLabel(s));
dot.add("states", st);
}
for (ATNState s : markedStates) {
if (s instanceof RuleStopState)
continue;
ST st = stlib.getInstanceOf("state");
st.add("name", "s" + s.stateNumber);
st.add("label", getStateLabel(s));
st.add("transitions", s.getTransitions());
dot.add("states", st);
}
return dot.render();
}
use of org.antlr.v4.runtime.atn.NotSetTransition in project antlr4 by tunnelvisionlabs.
the class ATNDeserializer method optimizeSets.
private static int optimizeSets(ATN atn, boolean preserveOrder) {
if (preserveOrder) {
// this optimization currently doesn't preserve edge order.
return 0;
}
int removedPaths = 0;
List<DecisionState> decisions = atn.decisionToState;
for (DecisionState decision : decisions) {
IntervalSet setTransitions = new IntervalSet();
for (int i = 0; i < decision.getNumberOfOptimizedTransitions(); i++) {
Transition epsTransition = decision.getOptimizedTransition(i);
if (!(epsTransition instanceof EpsilonTransition)) {
continue;
}
if (epsTransition.target.getNumberOfOptimizedTransitions() != 1) {
continue;
}
Transition transition = epsTransition.target.getOptimizedTransition(0);
if (!(transition.target instanceof BlockEndState)) {
continue;
}
if (transition instanceof NotSetTransition) {
// TODO: not yet implemented
continue;
}
if (transition instanceof AtomTransition || transition instanceof RangeTransition || transition instanceof SetTransition) {
setTransitions.add(i);
}
}
if (setTransitions.size() <= 1) {
continue;
}
List<Transition> optimizedTransitions = new ArrayList<Transition>();
for (int i = 0; i < decision.getNumberOfOptimizedTransitions(); i++) {
if (!setTransitions.contains(i)) {
optimizedTransitions.add(decision.getOptimizedTransition(i));
}
}
ATNState blockEndState = decision.getOptimizedTransition(setTransitions.getMinElement()).target.getOptimizedTransition(0).target;
IntervalSet matchSet = new IntervalSet();
for (int i = 0; i < setTransitions.getIntervals().size(); i++) {
Interval interval = setTransitions.getIntervals().get(i);
for (int j = interval.a; j <= interval.b; j++) {
Transition matchTransition = decision.getOptimizedTransition(j).target.getOptimizedTransition(0);
if (matchTransition instanceof NotSetTransition) {
throw new UnsupportedOperationException("Not yet implemented.");
} else {
matchSet.addAll(matchTransition.label());
}
}
}
Transition newTransition;
if (matchSet.getIntervals().size() == 1) {
if (matchSet.size() == 1) {
newTransition = new AtomTransition(blockEndState, matchSet.getMinElement());
} else {
Interval matchInterval = matchSet.getIntervals().get(0);
newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b);
}
} else {
newTransition = new SetTransition(blockEndState, matchSet);
}
ATNState setOptimizedState = new BasicState();
setOptimizedState.setRuleIndex(decision.ruleIndex);
atn.addState(setOptimizedState);
setOptimizedState.addTransition(newTransition);
optimizedTransitions.add(new EpsilonTransition(setOptimizedState));
removedPaths += decision.getNumberOfOptimizedTransitions() - optimizedTransitions.size();
if (decision.isOptimized()) {
while (decision.getNumberOfOptimizedTransitions() > 0) {
decision.removeOptimizedTransition(decision.getNumberOfOptimizedTransitions() - 1);
}
}
for (Transition transition : optimizedTransitions) {
decision.addOptimizedTransition(transition);
}
}
if (ParserATNSimulator.debug) {
System.out.println("ATN runtime optimizer removed " + removedPaths + " paths by collapsing sets.");
}
return removedPaths;
}
use of org.antlr.v4.runtime.atn.NotSetTransition in project antlr4 by tunnelvisionlabs.
the class ATNPrinter method asString.
public String asString() {
if (start == null)
return null;
marked = new HashSet<ATNState>();
work = new ArrayList<ATNState>();
work.add(start);
StringBuilder buf = new StringBuilder();
ATNState s;
while (!work.isEmpty()) {
s = work.remove(0);
if (marked.contains(s))
continue;
int n = s.getNumberOfTransitions();
// System.out.println("visit "+s+"; edges="+n);
marked.add(s);
for (int i = 0; i < n; i++) {
Transition t = s.transition(i);
if (!(s instanceof RuleStopState)) {
// don't add follow states to work
if (t instanceof RuleTransition)
work.add(((RuleTransition) t).followState);
else
work.add(t.target);
}
buf.append(getStateString(s));
if (t instanceof EpsilonTransition) {
buf.append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof RuleTransition) {
buf.append("-").append(g.getRule(((RuleTransition) t).ruleIndex).name).append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof ActionTransition) {
ActionTransition a = (ActionTransition) t;
buf.append("-").append(a.toString()).append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof SetTransition) {
SetTransition st = (SetTransition) t;
boolean not = st instanceof NotSetTransition;
if (g.isLexer()) {
buf.append("-").append(not ? "~" : "").append(st.toString()).append("->").append(getStateString(t.target)).append('\n');
} else {
buf.append("-").append(not ? "~" : "").append(st.label().toString(g.getVocabulary())).append("->").append(getStateString(t.target)).append('\n');
}
} else if (t instanceof AtomTransition) {
AtomTransition a = (AtomTransition) t;
String label = g.getTokenDisplayName(a.label);
buf.append("-").append(label).append("->").append(getStateString(t.target)).append('\n');
} else {
buf.append("-").append(t.toString()).append("->").append(getStateString(t.target)).append('\n');
}
}
}
return buf.toString();
}
use of org.antlr.v4.runtime.atn.NotSetTransition in project antlr4 by antlr.
the class ATNPrinter method asString.
public String asString() {
if (start == null)
return null;
marked = new HashSet<ATNState>();
work = new ArrayList<ATNState>();
work.add(start);
StringBuilder buf = new StringBuilder();
ATNState s;
while (!work.isEmpty()) {
s = work.remove(0);
if (marked.contains(s))
continue;
int n = s.getNumberOfTransitions();
// System.out.println("visit "+s+"; edges="+n);
marked.add(s);
for (int i = 0; i < n; i++) {
Transition t = s.transition(i);
if (!(s instanceof RuleStopState)) {
// don't add follow states to work
if (t instanceof RuleTransition)
work.add(((RuleTransition) t).followState);
else
work.add(t.target);
}
buf.append(getStateString(s));
if (t instanceof EpsilonTransition) {
buf.append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof RuleTransition) {
buf.append("-").append(g.getRule(((RuleTransition) t).ruleIndex).name).append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof ActionTransition) {
ActionTransition a = (ActionTransition) t;
buf.append("-").append(a.toString()).append("->").append(getStateString(t.target)).append('\n');
} else if (t instanceof SetTransition) {
SetTransition st = (SetTransition) t;
boolean not = st instanceof NotSetTransition;
if (g.isLexer()) {
buf.append("-").append(not ? "~" : "").append(st.toString()).append("->").append(getStateString(t.target)).append('\n');
} else {
buf.append("-").append(not ? "~" : "").append(st.label().toString(g.getVocabulary())).append("->").append(getStateString(t.target)).append('\n');
}
} else if (t instanceof AtomTransition) {
AtomTransition a = (AtomTransition) t;
String label = g.getTokenDisplayName(a.label);
buf.append("-").append(label).append("->").append(getStateString(t.target)).append('\n');
} else {
buf.append("-").append(t.toString()).append("->").append(getStateString(t.target)).append('\n');
}
}
}
return buf.toString();
}
Aggregations