This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch dev-new-parser
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/dev-new-parser by this push:
new 6ffe4583dd [new-parser] Complete support for built-in operators
(after, before) (#5812)
6ffe4583dd is described below
commit 6ffe4583dd427d57fd395166d3784e6ffa521360
Author: Jiří Locker <[email protected]>
AuthorDate: Tue Apr 2 10:09:58 2024 +0200
[new-parser] Complete support for built-in operators (after, before) (#5812)
* Improve no viable alternative example
* Complete support for built-in operators
* Enable soundslike test
* Remove obsolete comment
Co-authored-by: Toshiya Kobayashi <[email protected]>
---------
Co-authored-by: Toshiya Kobayashi <[email protected]>
---
.../drl/parser/antlr4/DRLExprParserTest.java | 47 ++++++++++---
.../drl/parser/antlr4/MiscDRLParserTest.java | 1 -
.../drools/drl/parser/antlr4/DRL6Expressions.g4 | 80 +++++++++++++---------
.../org/drools/drl/parser/antlr4/DRLParser.g4 | 43 ++++++++----
4 files changed, 113 insertions(+), 58 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 e32f287beb..3f3b256dd5 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
@@ -19,6 +19,10 @@
package org.drools.drl.parser.antlr4;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+
+import java.util.Arrays;
+import java.util.List;
import org.drools.drl.ast.descr.AtomicExprDescr;
import org.drools.drl.ast.descr.BindingDescr;
@@ -27,11 +31,13 @@ import org.drools.drl.ast.descr.ConstraintConnectiveDescr;
import org.drools.drl.ast.descr.RelationalExprDescr;
import org.drools.drl.parser.DrlExprParser;
import org.drools.drl.parser.DroolsParserException;
+import org.drools.drl.parser.impl.Operator;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.kie.internal.builder.conf.LanguageLevelOption;
@@ -212,9 +218,22 @@ public class DRLExprParserTest {
assertThat(bind.getExpression()).isEqualTo("y[z].foo");
}
- @Test
- public void testDrlKeywordMethodCall() throws Exception {
- String source = "x.contains( 1, a )";
+ private static final List<Operator.BuiltInOperator>
nonKeywordBuiltInOperators = Arrays.asList(
+ Operator.BuiltInOperator.EQUAL,
+ Operator.BuiltInOperator.NOT_EQUAL,
+ Operator.BuiltInOperator.LESS,
+ Operator.BuiltInOperator.LESS_OR_EQUAL,
+ Operator.BuiltInOperator.GREATER,
+ Operator.BuiltInOperator.GREATER_OR_EQUAL
+ );
+
+ @ParameterizedTest
+ @EnumSource(Operator.BuiltInOperator.class)
+ public void testDrlKeywordMethodCall(Operator.BuiltInOperator operator)
throws Exception {
+ // Skip operators that cannot be used as method names (==, !=, <,
etc.).
+ assumeFalse(nonKeywordBuiltInOperators.contains(operator));
+
+ String source = String.format("x.%s( 1, a )", operator.getSymbol());
ConstraintConnectiveDescr result = parser.parse( source );
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();
@@ -222,12 +241,18 @@ public class DRLExprParserTest {
assertThat(result.getDescrs().size()).isEqualTo(1);
AtomicExprDescr descr = (AtomicExprDescr) result.getDescrs().get( 0 );
- assertThat(descr.getExpression()).isEqualTo("x.contains( 1, a )");
+ assertThat(descr.getExpression()).isEqualTo(source);
}
- @Test
- public void testDrlKeywordMethodCallBinding() throws Exception {
- String source = "$x : x.contains( 1, a )";
+ @ParameterizedTest
+ @EnumSource(Operator.BuiltInOperator.class)
+ public void testDrlKeywordMethodCallBinding(Operator.BuiltInOperator
operator) throws Exception {
+ // Skip operators that cannot be used as method names (==, !=, <,
etc.).
+ assumeFalse(nonKeywordBuiltInOperators.contains(operator));
+
+ String expressionSource = String.format("x.%s( 1, a )",
operator.getSymbol());
+ String bindingVariableSource = "$x";
+ String source = bindingVariableSource + " : " + expressionSource;
ConstraintConnectiveDescr result = parser.parse( source );
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();
@@ -235,8 +260,8 @@ public class DRLExprParserTest {
assertThat(result.getDescrs().size()).isEqualTo(1);
BindingDescr bind = (BindingDescr) result.getDescrs().get( 0 );
- assertThat(bind.getVariable()).isEqualTo("$x");
- assertThat(bind.getExpression()).isEqualTo("x.contains( 1, a )");
+ assertThat(bind.getVariable()).isEqualTo(bindingVariableSource);
+ assertThat(bind.getExpression()).isEqualTo(expressionSource);
}
@Test
@@ -388,7 +413,7 @@ public class DRLExprParserTest {
}
@Test
public void testNoViableAlt() {
- String source = "a~a";
+ String source = "x.int";
parser.parse(source);
assertThat(parser.hasErrors()).isTrue();
assertThat(parser.getErrors()).hasSize(1);
@@ -398,6 +423,6 @@ public class DRLExprParserTest {
assertThat(exception.getColumn()).isEqualTo(2);
assertThat(exception.getOffset()).isEqualTo(2);
assertThat(exception.getMessage())
- .isEqualToIgnoringCase("[ERR 101] Line 1:2 no viable
alternative at input 'a'");
+ .isEqualToIgnoringCase("[ERR 101] Line 1:2 no viable
alternative at input '.int'");
}
}
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 86beaa4e13..fa961b876a 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
@@ -1980,7 +1980,6 @@ class MiscDRLParserTest {
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();
}
- @Disabled("Priority : Low | Implement soundslike")
@Test
public void parse_SoundsLike() throws Exception {
final PackageDescr pkg = parseAndGetPackageDescrFromFile(
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 ee5ce23259..47e01001a6 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,9 +162,32 @@ typeArgument
| QUESTION ((extends_key | super_key) type)?
;
+// matches any identifiers including acceptable java keywords (defined in
JavaParser.g4) and drl keywords
+drlIdentifier returns [Token token]
+ : drlKeywords
+ | IDENTIFIER
+ | MODULE
+ | OPEN
+ | REQUIRES
+ | EXPORTS
+ | OPENS
+ | TO
+ | USES
+ | PROVIDES
+ | WITH
+ | TRANSITIVE
+ | YIELD
+ | SEALED
+ | PERMITS
+ | RECORD
+ | VAR
+ | THIS
+ ;
+
// matches any drl keywords
drlKeywords returns [Token token]
- : DRL_UNIT
+ : builtInOperator
+ | DRL_UNIT
| DRL_FUNCTION
| DRL_GLOBAL
| DRL_DECLARE
@@ -179,12 +202,6 @@ drlKeywords returns [Token token]
| DRL_NOT
| DRL_IN
| DRL_FROM
- | DRL_MATCHES
- | DRL_MEMBEROF
- | DRL_CONTAINS
- | DRL_EXCLUDES
- | DRL_SOUNDSLIKE
- | DRL_STR
| DRL_ACCUMULATE
| DRL_ACC
| DRL_INIT
@@ -211,26 +228,26 @@ drlKeywords returns [Token token]
| DRL_DURATION
;
-// matches any identifiers including acceptable java keywords (defined in
JavaParser.g4) and drl keywords
-drlIdentifier returns [Token token]
- : drlKeywords
- | IDENTIFIER
- | MODULE
- | OPEN
- | REQUIRES
- | EXPORTS
- | OPENS
- | TO
- | USES
- | PROVIDES
- | WITH
- | TRANSITIVE
- | YIELD
- | SEALED
- | PERMITS
- | RECORD
- | VAR
- | THIS
+builtInOperator returns[Token token]
+ : DRL_CONTAINS
+ | DRL_EXCLUDES
+ | DRL_MATCHES
+ | DRL_MEMBEROF
+ | DRL_SOUNDSLIKE
+ | DRL_AFTER
+ | DRL_BEFORE
+ | DRL_COINCIDES
+ | DRL_DURING
+ | DRL_FINISHED_BY
+ | DRL_FINISHES
+ | DRL_INCLUDES
+ | DRL_MEETS
+ | DRL_MET_BY
+ | DRL_OVERLAPPED_BY
+ | DRL_OVERLAPS
+ | DRL_STARTED_BY
+ | DRL_STARTS
+ | DRL_STR
;
// --------------------------------------------------------
@@ -908,11 +925,12 @@ in_key
;
operator_key
- // At the moment, we list possible DRLLexer tokens here, but we may be able
to improve this by isolating lexers. IDENTIFIER is required to accept custom
operators
- // We need to keep this semantic predicate for custom operators
- : {(helper.isPluggableEvaluator(false))}?
id=(IDENTIFIER|DRL_MATCHES|DRL_MEMBEROF|DRL_CONTAINS|DRL_EXCLUDES|DRL_SOUNDSLIKE|DRL_STR)
{ helper.emit($id, DroolsEditorType.KEYWORD); }
+ // IDENTIFIER is required to accept custom operators. We need to keep this
semantic predicate for custom operators
+ : {(helper.isPluggableEvaluator(false))}? id=IDENTIFIER {
helper.emit($id, DroolsEditorType.KEYWORD); }
+ | op=builtInOperator { helper.emit($op.token,
DroolsEditorType.KEYWORD); }
;
neg_operator_key
- : {(helper.isPluggableEvaluator(true))}?
id=(IDENTIFIER|DRL_MATCHES|DRL_MEMBEROF|DRL_CONTAINS|DRL_EXCLUDES|DRL_SOUNDSLIKE|DRL_STR)
{ helper.emit($id, DroolsEditorType.KEYWORD); }
+ : {(helper.isPluggableEvaluator(true))}? id=IDENTIFIER {
helper.emit($id, DroolsEditorType.KEYWORD); }
+ | op=builtInOperator { helper.emit($op.token,
DroolsEditorType.KEYWORD); }
;
diff --git
a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRLParser.g4
b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRLParser.g4
index 8c48c7def4..90b9801e42 100644
---
a/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRLParser.g4
+++
b/drools-drl/drools-drl-parser/src/main/antlr4/org/drools/drl/parser/antlr4/DRLParser.g4
@@ -148,7 +148,7 @@ inExpression : left=relationalExpression ( 'not'? 'in'
LPAREN drlExpression (COM
relationalExpression : left=drlExpression (right=orRestriction)* ;
orRestriction : left=andRestriction (OR right=andRestriction)* ;
andRestriction : left=singleRestriction (AND right=singleRestriction)* ;
-singleRestriction : op=relationalOperator drlExpression ;
+singleRestriction : op=relationalOperator squareArguments? drlExpression ;
// OOPath
xpathSeparator : DIV | QUESTION_DIV ;
@@ -167,13 +167,7 @@ relationalOperator
| temporalOperator
;
-drlRelationalOperator
- : DRL_NOT? DRL_MATCHES
- | DRL_NOT? DRL_MEMBEROF
- | DRL_NOT? DRL_CONTAINS
- | DRL_NOT? DRL_EXCLUDES
- | DRL_NOT? DRL_SOUNDSLIKE
- | DRL_NOT? DRL_STR LBRACK IDENTIFIER RBRACK ;
+drlRelationalOperator : DRL_NOT? builtInOperator ;
/* function := FUNCTION type? ID parameters(typed) chunk_{_} */
functiondef : DRL_FUNCTION typeTypeOrVoid? IDENTIFIER formalParameters
drlBlock ;
@@ -207,7 +201,8 @@ drlIdentifier
;
drlKeywords
- : DRL_UNIT
+ : builtInOperator
+ | DRL_UNIT
| DRL_FUNCTION
| DRL_GLOBAL
| DRL_DECLARE
@@ -222,12 +217,6 @@ drlKeywords
| DRL_NOT
| DRL_IN
| DRL_FROM
- | DRL_MATCHES
- | DRL_MEMBEROF
- | DRL_CONTAINS
- | DRL_EXCLUDES
- | DRL_SOUNDSLIKE
- | DRL_STR
| DRL_ACCUMULATE
| DRL_ACC
| DRL_INIT
@@ -254,6 +243,28 @@ drlKeywords
| DRL_DURATION
;
+builtInOperator
+ : DRL_CONTAINS
+ | DRL_EXCLUDES
+ | DRL_MATCHES
+ | DRL_MEMBEROF
+ | DRL_SOUNDSLIKE
+ | DRL_AFTER
+ | DRL_BEFORE
+ | DRL_COINCIDES
+ | DRL_DURING
+ | DRL_FINISHED_BY
+ | DRL_FINISHES
+ | DRL_INCLUDES
+ | DRL_MEETS
+ | DRL_MET_BY
+ | DRL_OVERLAPPED_BY
+ | DRL_OVERLAPS
+ | DRL_STARTED_BY
+ | DRL_STARTS
+ | DRL_STR
+ ;
+
/* extending JavaParser expression */
drlExpression
: drlPrimary
@@ -348,6 +359,8 @@ drlLiteral
| TIME_INTERVAL
;
+squareArguments : LBRACK expressionList? RBRACK ;
+
inlineListExpression
: LBRACK expressionList? RBRACK
;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]