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:
Sam Harwell 2013-01-16 12:38:55 -06:00
parent 8e32d7b695
commit 9ccdca49bb
3 changed files with 19 additions and 0 deletions

View File

@ -145,6 +145,10 @@ public class LeftRecursiveRuleTransformer {
r.recPrimaryAlts = new ArrayList<LeftRecursiveRuleAltInfo>(); r.recPrimaryAlts = new ArrayList<LeftRecursiveRuleAltInfo>();
r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.prefixAlts); r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.prefixAlts);
r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.otherAlts); 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 = new OrderedHashMap<Integer, LeftRecursiveRuleAltInfo>();
r.recOpAlts.putAll(leftRecursiveRuleWalker.binaryAlts); r.recOpAlts.putAll(leftRecursiveRuleWalker.binaryAlts);
r.recOpAlts.putAll(leftRecursiveRuleWalker.ternaryAlts); r.recOpAlts.putAll(leftRecursiveRuleWalker.ternaryAlts);

View File

@ -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), 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), 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), 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 // Backward incompatibility errors
V3_TREE_GRAMMAR(200, "tree grammars are not supported in ANTLR 4", ErrorSeverity.ERROR), V3_TREE_GRAMMAR(200, "tree grammars are not supported in ANTLR 4", ErrorSeverity.ERROR),

View File

@ -30,6 +30,7 @@
package org.antlr.v4.test; package org.antlr.v4.test;
import org.antlr.v4.tool.ErrorType;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -373,6 +374,19 @@ public class TestLeftRecursion extends BaseTest {
stderrDuringParse); 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) { public void runTests(String grammar, String[] tests, String startRule) {
rawGenerateAndBuildRecognizer("T.g4", grammar, "TParser", "TLexer"); rawGenerateAndBuildRecognizer("T.g4", grammar, "TParser", "TLexer");
writeRecognizerAndCompile("TParser", writeRecognizerAndCompile("TParser",