use of org.antlr.v4.runtime.atn.RuleTransition in project antlr4 by tunnelvisionlabs.
the class ATN method getExpectedTokens.
/**
* Computes the set of input symbols which could follow ATN state number
* {@code stateNumber} in the specified full {@code context}. This method
* considers the complete parser context, but does not evaluate semantic
* predicates (i.e. all predicates encountered during the calculation are
* assumed true). If a path in the ATN exists from the starting state to the
* {@link RuleStopState} of the outermost context without matching any
* symbols, {@link Token#EOF} is added to the returned set.
*
* <p>If {@code context} is {@code null}, it is treated as
* {@link ParserRuleContext#EMPTY}.</p>
*
* <p>Note that this does NOT give you the set of all tokens that could
* appear at a given token position in the input phrase. In other words, it
* does not answer:</p>
*
* <quote>"Given a specific partial input phrase, return the set of all
* tokens that can follow the last token in the input phrase."</quote>
*
* <p>The big difference is that with just the input, the parser could land
* right in the middle of a lookahead decision. Getting all
* <em>possible</em> tokens given a partial input stream is a separate
* computation. See https://github.com/antlr/antlr4/issues/1428</p>
*
* <p>For this function, we are specifying an ATN state and call stack to
* compute what token(s) can come next and specifically: outside of a
* lookahead decision. That is what you want for error reporting and
* recovery upon parse error.</p>
*
* @param stateNumber the ATN state number
* @param context the full parse context
* @return The set of potentially valid input symbols which could follow the
* specified state in the specified context.
* @throws IllegalArgumentException if the ATN does not contain a state with
* number {@code stateNumber}
*/
@NotNull
public IntervalSet getExpectedTokens(int stateNumber, @Nullable RuleContext context) {
if (stateNumber < 0 || stateNumber >= states.size()) {
throw new IllegalArgumentException("Invalid state number.");
}
RuleContext ctx = context;
ATNState s = states.get(stateNumber);
IntervalSet following = nextTokens(s);
if (!following.contains(Token.EPSILON)) {
return following;
}
IntervalSet expected = new IntervalSet();
expected.addAll(following);
expected.remove(Token.EPSILON);
while (ctx != null && ctx.invokingState >= 0 && following.contains(Token.EPSILON)) {
ATNState invokingState = states.get(ctx.invokingState);
RuleTransition rt = (RuleTransition) invokingState.transition(0);
following = nextTokens(rt.followState);
expected.addAll(following);
expected.remove(Token.EPSILON);
ctx = ctx.parent;
}
if (following.contains(Token.EPSILON)) {
expected.add(Token.EOF);
}
return expected;
}
use of org.antlr.v4.runtime.atn.RuleTransition 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.RuleTransition in project antlr4 by tunnelvisionlabs.
the class ParserATNFactory method elemList.
@NotNull
public Handle elemList(@NotNull List<Handle> els) {
int n = els.size();
for (int i = 0; i < n - 1; i++) {
// hook up elements (visit all but last)
Handle el = els.get(i);
// if el is of form o-x->o for x in {rule, action, pred, token, ...}
// and not last in alt
Transition tr = null;
if (el.left.getNumberOfTransitions() == 1)
tr = el.left.transition(0);
boolean isRuleTrans = tr instanceof RuleTransition;
if (el.left.getStateType() == ATNState.BASIC && el.right.getStateType() == ATNState.BASIC && tr != null && (isRuleTrans && ((RuleTransition) tr).followState == el.right || tr.target == el.right)) {
// we can avoid epsilon edge to next el
if (isRuleTrans)
((RuleTransition) tr).followState = els.get(i + 1).left;
else
tr.target = els.get(i + 1).left;
// we skipped over this state
atn.removeState(el.right);
} else {
// need epsilon if previous block's right end node is complicated
epsilon(el.right, els.get(i + 1).left);
}
}
Handle first = els.get(0);
Handle last = els.get(n - 1);
if (first == null || last == null) {
g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null");
}
return new Handle(first.left, last.right);
}
Aggregations