From 4aed056c6b39da98f70619d6d908a87e460d37cf Mon Sep 17 00:00:00 2001 From: Toshiya Kobayashi Date: Fri, 17 May 2024 17:22:27 +0900 Subject: [PATCH] [incubator-kie-drools-5818] [new-parser] Parsing fails if a Java keyword appears in a qualified name --- .../drl/parser/antlr4/DRLExprParserTest.java | 23 -------- .../drl/parser/antlr4/MiscDRLParserTest.java | 19 ++++++ .../drl/parser/antlr4/ParserTestUtils.java | 17 ++++++ .../drl/parser/antlr4/DRL6Expressions.g4 | 59 ++++++++++++++++++- 4 files changed, 92 insertions(+), 26 deletions(-) diff --git a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java index 2a6d4e96a6a..3a2aee51167 100644 --- a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java +++ b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java @@ -440,29 +440,6 @@ public void testExtraneousInput() { } } - @Test - public void testNoViableAlt() { - String source = "x.int"; - parser.parse(source); - - // Backward Compatibility Notes: - // Old expr parser (DRL6Expressions) allows this expression because it's too tolerant (fail at runtime anyway). - // Backward compatibility doesn't seem to be required in this case. (But we may align with the old tolerant behavior.) - if (DrlParser.ANTLR4_PARSER_ENABLED) { - assertThat(parser.hasErrors()).isTrue(); - assertThat(parser.getErrors()).hasSize(1); - DroolsParserException exception = parser.getErrors().get(0); - assertThat(exception.getErrorCode()).isEqualTo("ERR 101"); - assertThat(exception.getLineNumber()).isEqualTo(1); - assertThat(exception.getColumn()).isEqualTo(2); - assertThat(exception.getOffset()).isEqualTo(2); - assertThat(exception.getMessage()) - .isEqualToIgnoringCase("[ERR 101] Line 1:2 no viable alternative at input '.int'"); - } else { - assertThat(parser.hasErrors()).isFalse(); - } - } - @Test void orWithMethodCall() { String source = "value == 10 || someMethod() == 4"; diff --git a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java index bf553765e26..85c8423ba89 100644 --- a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java +++ b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/MiscDRLParserTest.java @@ -5103,4 +5103,23 @@ void errorMessage_shouldNotContainEmptyString() { assertThat(parser.hasErrors()).isTrue(); assertThat(parser.getErrors()).extracting(DroolsError::getMessage).doesNotContain(""); } + + @ParameterizedTest + @MethodSource("org.drools.drl.parser.antlr4.ParserTestUtils#javaKeywords") + void javaKeywordsInPackage(String keyword) { + String pkgName = "org.drools." + keyword; + String text = "package " + pkgName + "\n" + + "rule R\n" + + "when\n" + + " $p : Person()\n" + + "then\n" + + "end\n"; + + PackageDescr pkg = parseAndGetPackageDescr(text); + + assertThat(pkg.getName()).isEqualTo(pkgName); + assertThat(pkg.getRules()).hasSize(1); + + assertThat(pkg.getRules().get(0).getName()).isEqualTo("R"); + } } diff --git a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/ParserTestUtils.java b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/ParserTestUtils.java index 270b8f8c37c..9d59344f376 100644 --- a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/ParserTestUtils.java +++ b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/ParserTestUtils.java @@ -18,10 +18,23 @@ */ package org.drools.drl.parser.antlr4; +import java.util.Arrays; +import java.util.List; + import org.drools.drl.parser.DrlParser; public class ParserTestUtils { + public static List javaKeywords = + Arrays.asList( + "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", + "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", + "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", + "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", + "while" + ); + private ParserTestUtils() { // It is a utility class, so it should not be instantiated. } @@ -39,4 +52,8 @@ public static DrlParser getParser() { public static void enableOldParser() { DrlParser.ANTLR4_PARSER_ENABLED = false; } + + public static List javaKeywords() { + return javaKeywords; + } } diff --git a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL6Expressions.g4 b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL6Expressions.g4 index 27734251f1e..3daf6ccf653 100644 --- a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL6Expressions.g4 +++ b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRL6Expressions.g4 @@ -162,6 +162,58 @@ typeArgument drlIdentifier returns [Token token] : drlKeywords | IDENTIFIER + // java keywords + | ABSTRACT + | ASSERT + | BOOLEAN + | BREAK + | BYTE + | CASE + | CATCH + | CHAR + | CLASS + | CONST + | CONTINUE + | DEFAULT + | DO + | DOUBLE + | ELSE + | ENUM + | EXTENDS + | FINAL + | FINALLY + | FLOAT + | FOR + | IF + | GOTO + | IMPLEMENTS + | IMPORT + | INSTANCEOF + | INT + | INTERFACE + | LONG + | NATIVE + | NEW + | PACKAGE + | PRIVATE + | PROTECTED + | PUBLIC + | RETURN + | SHORT + | STATIC + | STRICTFP + | SUPER + | SWITCH + | SYNCHRONIZED + | THIS + | THROW + | THROWS + | TRANSIENT + | TRY + | VOID + | VOLATILE + | WHILE + // Module related keywords | MODULE | OPEN | REQUIRES @@ -172,12 +224,13 @@ drlIdentifier returns [Token token] | PROVIDES | WITH | TRANSITIVE + // other java keywords + | VAR | YIELD + | RECORD | SEALED | PERMITS - | RECORD - | VAR - | THIS + | NON_SEALED ; // matches any drl keywords