Merge pull request #414 from parrt/master

Add tests for ungrammatical tree patterns. Fixes #413
This commit is contained in:
Terence Parr 2014-01-15 11:16:12 -08:00
commit e98a2b1b67
2 changed files with 91 additions and 0 deletions

View File

@ -37,6 +37,7 @@ import org.antlr.v4.runtime.ListTokenSource;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserInterpreter;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.misc.MultiMap;
@ -114,6 +115,11 @@ public class ParseTreePatternMatcher {
}
}
// Fixes https://github.com/antlr/antlr4/issues/413
// "Tree pattern compilation doesn't check for a complete parse"
public static class StartRuleDoesNotConsumeFullPattern extends RuntimeException {
}
/**
* This is the backing field for {@link #getLexer()}.
*/
@ -222,10 +228,18 @@ public class ParseTreePatternMatcher {
tree = parserInterp.parse(patternRuleIndex);
// System.out.println("pattern tree = "+tree.toStringTree(parserInterp));
}
catch (RecognitionException re) {
throw re;
}
catch (Exception e) {
throw new CannotInvokeStartRule(e);
}
// Make sure tree pattern compilation checks for a complete parse
if ( tokens.LA(1)!=Token.EOF ) {
throw new StartRuleDoesNotConsumeFullPattern();
}
return new ParseTreePattern(this, pattern, patternRuleIndex, tree);
}

View File

@ -2,7 +2,9 @@ package org.antlr.v4.test;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.InputMismatchException;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
@ -119,6 +121,81 @@ public class TestParseTreeMatcher extends BaseTest {
assertEquals(expected, results);
}
@Test
public void testCompilingPatternConsumesAllTokens() throws Exception {
String grammar =
"grammar X2;\n" +
"s : ID '=' expr ';' ;\n" +
"expr : ID | INT ;\n" +
"ID : [a-z]+ ;\n" +
"INT : [0-9]+ ;\n" +
"WS : [ \\r\\n\\t]+ -> skip ;\n";
boolean ok =
rawGenerateAndBuildRecognizer("X2.g4", grammar, "X2Parser", "X2Lexer", false);
assertTrue(ok);
ParseTreePatternMatcher m = getPatternMatcher("X2");
boolean failed = false;
try {
m.compile("<ID> = <expr> ; extra", m.getParser().getRuleIndex("s"));
}
catch (ParseTreePatternMatcher.StartRuleDoesNotConsumeFullPattern e) {
failed = true;
}
assertTrue(failed);
}
@Test
public void testPatternMatchesStartRule() throws Exception {
String grammar =
"grammar X2;\n" +
"s : ID '=' expr ';' ;\n" +
"expr : ID | INT ;\n" +
"ID : [a-z]+ ;\n" +
"INT : [0-9]+ ;\n" +
"WS : [ \\r\\n\\t]+ -> skip ;\n";
boolean ok =
rawGenerateAndBuildRecognizer("X2.g4", grammar, "X2Parser", "X2Lexer", false);
assertTrue(ok);
ParseTreePatternMatcher m = getPatternMatcher("X2");
boolean failed = false;
try {
m.compile("<ID> ;", m.getParser().getRuleIndex("s"));
}
catch (InputMismatchException e) {
failed = true;
}
assertTrue(failed);
}
@Test
public void testPatternMatchesStartRule2() throws Exception {
String grammar =
"grammar X2;\n" +
"s : ID '=' expr ';' | expr ';' ;\n" +
"expr : ID | INT ;\n" +
"ID : [a-z]+ ;\n" +
"INT : [0-9]+ ;\n" +
"WS : [ \\r\\n\\t]+ -> skip ;\n";
boolean ok =
rawGenerateAndBuildRecognizer("X2.g4", grammar, "X2Parser", "X2Lexer", false);
assertTrue(ok);
ParseTreePatternMatcher m = getPatternMatcher("X2");
boolean failed = false;
try {
m.compile("<ID> <ID> ;", m.getParser().getRuleIndex("s"));
}
catch (NoViableAltException e) {
failed = true;
}
assertTrue(failed);
}
@Test
public void testHiddenTokensNotSeenByTreePatternParser() throws Exception {
String grammar =