use of org.antlr.v4.runtime.atn.LL1Analyzer in project antlr4 by antlr.
the class ATN method nextTokens.
/** Compute the set of valid tokens that can occur starting in state {@code s}.
* If {@code ctx} is null, the set of tokens will not include what can follow
* the rule surrounding {@code s}. In other words, the set will be
* restricted to tokens reachable staying within {@code s}'s rule.
*/
public IntervalSet nextTokens(ATNState s, RuleContext ctx) {
LL1Analyzer anal = new LL1Analyzer(this);
IntervalSet next = anal.LOOK(s, ctx);
return next;
}
use of org.antlr.v4.runtime.atn.LL1Analyzer 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.LL1Analyzer in project antlr4 by antlr.
the class AnalysisPipeline method processParser.
protected void processParser() {
g.decisionLOOK = new ArrayList<IntervalSet[]>(g.atn.getNumberOfDecisions() + 1);
for (DecisionState s : g.atn.decisionToState) {
g.tool.log("LL1", "\nDECISION " + s.decision + " in rule " + g.getRule(s.ruleIndex).name);
IntervalSet[] look;
if (s.nonGreedy) {
// nongreedy decisions can't be LL(1)
look = new IntervalSet[s.getNumberOfTransitions() + 1];
} else {
LL1Analyzer anal = new LL1Analyzer(g.atn);
look = anal.getDecisionLookahead(s);
g.tool.log("LL1", "look=" + Arrays.toString(look));
}
assert s.decision + 1 >= g.decisionLOOK.size();
Utils.setSize(g.decisionLOOK, s.decision + 1);
g.decisionLOOK.set(s.decision, look);
g.tool.log("LL1", "LL(1)? " + disjoint(look));
}
}
use of org.antlr.v4.runtime.atn.LL1Analyzer in project antlr4 by antlr.
the class AnalysisPipeline method processLexer.
protected void processLexer() {
// make sure all non-fragment lexer rules must match at least one symbol
for (Rule rule : g.rules.values()) {
if (rule.isFragment()) {
continue;
}
LL1Analyzer analyzer = new LL1Analyzer(g.atn);
IntervalSet look = analyzer.LOOK(g.atn.ruleToStartState[rule.index], null);
if (look.contains(Token.EPSILON)) {
g.tool.errMgr.grammarError(ErrorType.EPSILON_TOKEN, g.fileName, ((GrammarAST) rule.ast.getChild(0)).getToken(), rule.name);
}
}
}
Aggregations