use of org.antlr.v4.runtime.atn.RuleStartState in project antlr4 by antlr.
the class ParserATNFactory method rule.
/* start->ruleblock->end */
@Override
public Handle rule(GrammarAST ruleAST, String name, Handle blk) {
Rule r = g.getRule(name);
RuleStartState start = atn.ruleToStartState[r.index];
epsilon(start, blk.left);
RuleStopState stop = atn.ruleToStopState[r.index];
epsilon(blk.right, stop);
Handle h = new Handle(start, stop);
// ATNPrinter ser = new ATNPrinter(g, h.left);
// System.out.println(ruleAST.toStringTree()+":\n"+ser.asString());
ruleAST.atnState = start;
return h;
}
use of org.antlr.v4.runtime.atn.RuleStartState in project antlr4 by antlr.
the class ParserATNFactory method createRuleStartAndStopATNStates.
/** Define all the rule begin/end ATNStates to solve forward reference
* issues.
*/
void createRuleStartAndStopATNStates() {
atn.ruleToStartState = new RuleStartState[g.rules.size()];
atn.ruleToStopState = new RuleStopState[g.rules.size()];
for (Rule r : g.rules.values()) {
RuleStartState start = newState(RuleStartState.class, r.ast);
RuleStopState stop = newState(RuleStopState.class, r.ast);
start.stopState = stop;
start.isLeftRecursiveRule = r instanceof LeftRecursiveRule;
start.setRuleIndex(r.index);
stop.setRuleIndex(r.index);
atn.ruleToStartState[r.index] = start;
atn.ruleToStopState[r.index] = stop;
}
}
use of org.antlr.v4.runtime.atn.RuleStartState in project antlr4 by antlr.
the class LeftRecursionDetector method check.
public void check() {
for (RuleStartState start : atn.ruleToStartState) {
//System.out.print("check "+start.rule.name);
rulesVisitedPerRuleCheck.clear();
rulesVisitedPerRuleCheck.add(start);
//FASerializer ser = new FASerializer(atn.g, start);
//System.out.print(":\n"+ser+"\n");
check(g.getRule(start.ruleIndex), start, new HashSet<ATNState>());
}
//System.out.println("cycles="+listOfRecursiveCycles);
if (!listOfRecursiveCycles.isEmpty()) {
g.tool.errMgr.leftRecursionCycles(g.fileName, listOfRecursiveCycles);
}
}
use of org.antlr.v4.runtime.atn.RuleStartState in project antlr4 by antlr.
the class LeftRecursionDetector method check.
/** From state s, look for any transition to a rule that is currently
* being traced. When tracing r, visitedPerRuleCheck has r
* initially. If you reach a rule stop state, return but notify the
* invoking rule that the called rule is nullable. This implies that
* invoking rule must look at follow transition for that invoking state.
*
* The visitedStates tracks visited states within a single rule so
* we can avoid epsilon-loop-induced infinite recursion here. Keep
* filling the cycles in listOfRecursiveCycles and also, as a
* side-effect, set leftRecursiveRules.
*/
public boolean check(Rule enclosingRule, ATNState s, Set<ATNState> visitedStates) {
if (s instanceof RuleStopState)
return true;
if (visitedStates.contains(s))
return false;
visitedStates.add(s);
//System.out.println("visit "+s);
int n = s.getNumberOfTransitions();
boolean stateReachesStopState = false;
for (int i = 0; i < n; i++) {
Transition t = s.transition(i);
if (t instanceof RuleTransition) {
RuleTransition rt = (RuleTransition) t;
Rule r = g.getRule(rt.ruleIndex);
if (rulesVisitedPerRuleCheck.contains((RuleStartState) t.target)) {
addRulesToCycle(enclosingRule, r);
} else {
// must visit if not already visited; mark target, pop when done
rulesVisitedPerRuleCheck.add((RuleStartState) t.target);
// send new visitedStates set per rule invocation
boolean nullable = check(r, t.target, new HashSet<ATNState>());
// we're back from visiting that rule
rulesVisitedPerRuleCheck.remove((RuleStartState) t.target);
if (nullable) {
stateReachesStopState |= check(enclosingRule, rt.followState, visitedStates);
}
}
} else if (t.isEpsilon()) {
stateReachesStopState |= check(enclosingRule, t.target, visitedStates);
}
// else ignore non-epsilon transitions
}
return stateReachesStopState;
}
use of org.antlr.v4.runtime.atn.RuleStartState in project antlr4 by antlr.
the class ParserATNFactory method _ruleRef.
public Handle _ruleRef(GrammarAST node) {
Rule r = g.getRule(node.getText());
if (r == null) {
g.tool.errMgr.grammarError(ErrorType.INTERNAL_ERROR, g.fileName, node.getToken(), "Rule " + node.getText() + " undefined");
return null;
}
RuleStartState start = atn.ruleToStartState[r.index];
ATNState left = newState(node);
ATNState right = newState(node);
int precedence = 0;
if (((GrammarASTWithOptions) node).getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME) != null) {
precedence = Integer.parseInt(((GrammarASTWithOptions) node).getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME));
}
RuleTransition call = new RuleTransition(start, r.index, precedence, right);
left.addTransition(call);
node.atnState = left;
return new Handle(left, right);
}
Aggregations