Add error 147: left recursive rule 'a' must contain an alternative which is not left recursive; fixes antlr/antlr4#140
This commit is contained in:
parent
8e32d7b695
commit
9ccdca49bb
|
@ -145,6 +145,10 @@ public class LeftRecursiveRuleTransformer {
|
|||
r.recPrimaryAlts = new ArrayList<LeftRecursiveRuleAltInfo>();
|
||||
r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.prefixAlts);
|
||||
r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.otherAlts);
|
||||
if (r.recPrimaryAlts.isEmpty()) {
|
||||
tool.errMgr.grammarError(ErrorType.NO_NON_LR_ALTS, g.fileName, ((GrammarAST)prevRuleAST.getChild(0)).getToken(), r.name);
|
||||
}
|
||||
|
||||
r.recOpAlts = new OrderedHashMap<Integer, LeftRecursiveRuleAltInfo>();
|
||||
r.recOpAlts.putAll(leftRecursiveRuleWalker.binaryAlts);
|
||||
r.recOpAlts.putAll(leftRecursiveRuleWalker.ternaryAlts);
|
||||
|
|
|
@ -129,6 +129,7 @@ public enum ErrorType {
|
|||
INVALID_LITERAL_IN_LEXER_SET(144, "multi-character literals are not allowed in lexer sets: <arg>", ErrorSeverity.ERROR),
|
||||
MODE_WITHOUT_RULES(145, "lexer mode '<arg>' must contain at least one non-fragment rule", ErrorSeverity.ERROR),
|
||||
EPSILON_TOKEN(146, "non-fragment lexer rule '<arg>' can match the empty string", ErrorSeverity.ERROR),
|
||||
NO_NON_LR_ALTS(147, "left recursive rule '<arg>' must contain an alternative which is not left recursive", ErrorSeverity.ERROR),
|
||||
|
||||
// Backward incompatibility errors
|
||||
V3_TREE_GRAMMAR(200, "tree grammars are not supported in ANTLR 4", ErrorSeverity.ERROR),
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
package org.antlr.v4.test;
|
||||
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -373,6 +374,19 @@ public class TestLeftRecursion extends BaseTest {
|
|||
stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test public void testCheckForNonLeftRecursiveRule() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : a ;\n" +
|
||||
"a : a ID\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String expected =
|
||||
"error(" + ErrorType.NO_NON_LR_ALTS.code + "): T.g4:3:0: left recursive rule 'a' must contain an alternative which is not left recursive\n";
|
||||
testErrors(new String[] { grammar, expected }, false);
|
||||
}
|
||||
|
||||
public void runTests(String grammar, String[] tests, String startRule) {
|
||||
rawGenerateAndBuildRecognizer("T.g4", grammar, "TParser", "TLexer");
|
||||
writeRecognizerAndCompile("TParser",
|
||||
|
|
Loading…
Reference in New Issue