use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by antlr.
the class ParserATNFactory method addRuleFollowLinks.
public void addRuleFollowLinks() {
for (ATNState p : atn.states) {
if (p != null && p.getStateType() == ATNState.BASIC && p.getNumberOfTransitions() == 1 && p.transition(0) instanceof RuleTransition) {
RuleTransition rt = (RuleTransition) p.transition(0);
addFollowLink(rt.ruleIndex, rt.followState);
}
}
}
use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by antlr.
the class ParserATNFactory method newState.
public ATNState newState(GrammarAST node) {
ATNState n = new BasicState();
n.setRuleIndex(currentRule.index);
atn.addState(n);
return n;
}
use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by antlr.
the class ParserATNFactory method addEOFTransitionToStartRules.
/**
* Add an EOF transition to any rule end ATNState that points to nothing
* (i.e., for all those rules not invoked by another rule). These
* are start symbols then.
*
* Return the number of grammar entry points; i.e., how many rules are
* not invoked by another rule (they can only be invoked from outside).
* These are the start rules.
*/
public int addEOFTransitionToStartRules() {
int n = 0;
// one unique EOF target for all rules
ATNState eofTarget = newState(null);
for (Rule r : g.rules.values()) {
ATNState stop = atn.ruleToStopState[r.index];
if (stop.getNumberOfTransitions() > 0)
continue;
n++;
Transition t = new AtomTransition(eofTarget, Token.EOF);
stop.addTransition(t);
}
return n;
}
use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by antlr.
the class ParserATNFactory method createATN.
@Override
public ATN createATN() {
_createATN(g.rules.values());
assert atn.maxTokenType == g.getMaxTokenType();
addRuleFollowLinks();
addEOFTransitionToStartRules();
ATNOptimizer.optimize(g, atn);
for (Triple<Rule, ATNState, ATNState> pair : preventEpsilonClosureBlocks) {
LL1Analyzer analyzer = new LL1Analyzer(atn);
ATNState blkStart = pair.b;
ATNState blkStop = pair.c;
IntervalSet lookahead = analyzer.LOOK(blkStart, blkStop, null);
if (lookahead.contains(org.antlr.v4.runtime.Token.EPSILON)) {
ErrorType errorType = pair.a instanceof LeftRecursiveRule ? ErrorType.EPSILON_LR_FOLLOW : ErrorType.EPSILON_CLOSURE;
g.tool.errMgr.grammarError(errorType, g.fileName, ((GrammarAST) pair.a.ast.getChild(0)).getToken(), pair.a.name);
}
}
optionalCheck: for (Triple<Rule, ATNState, ATNState> pair : preventEpsilonOptionalBlocks) {
int bypassCount = 0;
for (int i = 0; i < pair.b.getNumberOfTransitions(); i++) {
ATNState startState = pair.b.transition(i).target;
if (startState == pair.c) {
bypassCount++;
continue;
}
LL1Analyzer analyzer = new LL1Analyzer(atn);
if (analyzer.LOOK(startState, pair.c, null).contains(org.antlr.v4.runtime.Token.EPSILON)) {
g.tool.errMgr.grammarError(ErrorType.EPSILON_OPTIONAL, g.fileName, ((GrammarAST) pair.a.ast.getChild(0)).getToken(), pair.a.name);
continue optionalCheck;
}
}
if (bypassCount != 1) {
throw new UnsupportedOperationException("Expected optional block with exactly 1 bypass alternative.");
}
}
return atn;
}
use of org.antlr.v4.runtime.atn.ATNState in project antlr4 by antlr.
the class ParserATNFactory method set.
/**
* From set build single edge graph {@code o->o-set->o}. To conform to
* what an alt block looks like, must have extra state on left.
* This also handles {@code ~A}, converted to {@code ~{A}} set.
*/
@Override
public Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert) {
ATNState left = newState(associatedAST);
ATNState right = newState(associatedAST);
IntervalSet set = new IntervalSet();
for (GrammarAST t : terminals) {
int ttype = g.getTokenType(t.getText());
set.add(ttype);
}
if (invert) {
left.addTransition(new NotSetTransition(right, set));
} else {
left.addTransition(new SetTransition(right, set));
}
associatedAST.atnState = left;
return new Handle(left, right);
}
Aggregations