Skip to content

Commit

Permalink
Fix NPE for undefined label, fix antlr#2788
Browse files Browse the repository at this point in the history
  • Loading branch information
KvanTTT committed Apr 8, 2022
1 parent 38de75b commit 9b89fd0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
18 changes: 18 additions & 0 deletions tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java
Original file line number Diff line number Diff line change
Expand Up @@ -542,4 +542,22 @@ public void testLabelsForTokensWithMixedTypesLRWithoutLabels() {

testErrors(test, false);
}

// ISSUE: https://github.com/antlr/antlr4/issues/2788
@Test public void testUndefinedLabel() {
String[] test = {
"grammar Test;" +
"root\n" +
" : root a\n" +
" | b [error]\n" +
" ;\n" +
"\n" +
"a: 'a';\n" +
"b: 'b';",

"error(" + ErrorType.INTERNAL_ERROR.code + "): Test.g4:2:30: internal error: Rule error undefined \n"
};

testErrors(test, false);
}
}
30 changes: 22 additions & 8 deletions tool/src/org/antlr/v4/automata/ParserATNFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -472,24 +472,38 @@ public Handle elemList(List<Handle> els) {
if ( el.left.getNumberOfTransitions()==1 ) tr = el.left.transition(0);
boolean isRuleTrans = tr instanceof RuleTransition;
if ( el.left.getStateType() == ATNState.BASIC &&
el.right != null &&
el.right.getStateType()== ATNState.BASIC &&
tr!=null && (isRuleTrans && ((RuleTransition)tr).followState == el.right || tr.target == el.right) )
{
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;
Handle handle = null;
if (i + 1 < els.size()) {
handle = els.get(i + 1);
}
if (handle != null) {
if (isRuleTrans) {
((RuleTransition) tr).followState = handle.left;
} else {
tr.target = handle.left;
}
}
atn.removeState(el.right); // we skipped over this state
}
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");
Handle last = els.get(n - 1);
ATNState left = null;
if (first != null) {
left = first.left;
}
return new Handle(first.left, last.right);
ATNState right = null;
if (last != null) {
right = last.right;
}
return new Handle(left, right);
}

/**
Expand Down

0 comments on commit 9b89fd0

Please sign in to comment.