Skip to content

Commit

Permalink
[incubator-kie-drools-5818] [new-parser] Parsing fails if a Java keyw… (
Browse files Browse the repository at this point in the history
apache#5958)

* [incubator-kie-drools-5818] [new-parser] Parsing fails if a Java keyword appears in a qualified name

* - Exclude 'new' from 'drlIdentifier' because of 'primary' ambiguity
- Add tests
  • Loading branch information
tkobayas committed Jun 11, 2024
1 parent 04c54cd commit 5e2a896
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,13 @@ public void testExtraneousInput() {

@Test
public void testNoViableAlt() {
String source = "x.int";
String source = "a~a";
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.)
// Old expr parser (DRL6Expressions) allows this expression and only takes "a" ignoring the invalid part "~a" without emitting an error.
// This is rather a bug in the old parser, and the new parser (ANTLR4) correctly emits an error for this case.
// Backward compatibility doesn't seem to be required in this case.
if (DrlParser.ANTLR4_PARSER_ENABLED) {
assertThat(parser.hasErrors()).isTrue();
assertThat(parser.getErrors()).hasSize(1);
Expand All @@ -457,7 +458,7 @@ public void testNoViableAlt() {
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'");
.isEqualToIgnoringCase("[ERR 101] Line 1:2 no viable alternative at input 'a'");
} else {
assertThat(parser.hasErrors()).isFalse();
}
Expand Down Expand Up @@ -564,4 +565,17 @@ void andWithMethodCallWithArg() {
assertThat(left.getExpression()).isEqualTo("someMethod(value)");
assertThat(right.getExpression()).isEqualTo("4");
}

@Test
void newBigDecimal() {
String source = "$bd : new BigDecimal(30)";
ConstraintConnectiveDescr result = parser.parse(source);
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();

assertThat(result.getDescrs().size()).isEqualTo(1);

BindingDescr bind = (BindingDescr) result.getDescrs().get(0);
assertThat(bind.getVariable()).isEqualTo("$bd");
assertThat(bind.getExpression()).isEqualTo("new BigDecimal(30)");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,25 @@
*/
package org.drools.drl.parser.antlr4;

import java.util.Arrays;
import java.util.List;

import org.drools.drl.parser.DrlParser;

public class ParserTestUtils {

// 'new' is not included because it cannot be included in drlIdentifier.
// See https://github.com/apache/incubator-kie-drools/pull/5958
public static List<String> 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",
"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.
}
Expand All @@ -39,4 +54,8 @@ public static DrlParser getParser() {
public static void enableOldParser() {
DrlParser.ANTLR4_PARSER_ENABLED = false;
}

public static List<String> javaKeywords() {
return javaKeywords;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 // avoid ambiguity with 'new_key creator' and 'drlIdentifier' in 'primary'
| 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
Expand All @@ -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
Expand Down

0 comments on commit 5e2a896

Please sign in to comment.