This is an automated email from the ASF dual-hosted git repository.

mariofusco pushed a commit to branch dev-new-parser
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git

commit 163438a0463bf56fdea4575084083851eb1356e3
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Thu Aug 24 16:16:16 2023 +0900

    [DROOLS-7288] Failed to parse complex parentheses (#27)
    
    * [DROOLS-7288] Failed to parse complex parentheses
    - bump to 8.43.0.Final
    
    * additional tests
---
 .../src/main/antlr4/org/drools/parser/DRLParser.g4 |  14 ++-
 .../java/org/drools/parser/DRLVisitorImpl.java     |  41 +++-----
 .../java/org/drools/parser/MiscDRLParserTest.java  | 112 +++++++++++++++++++--
 3 files changed, 130 insertions(+), 37 deletions(-)

diff --git 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
index af10b445e9..c150a480e4 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
+++ 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4
@@ -36,10 +36,15 @@ globaldef : DRL_GLOBAL type drlIdentifier SEMI? ;
 
 ruledef : DRL_RULE name=stringId (EXTENDS stringId)? drlAnnotation* 
attributes? lhs rhs DRL_END ;
 
-lhs : DRL_WHEN lhsExpression? ;
-lhsExpression : lhsOr+ ;
-lhsOr : LPAREN DRL_OR lhsAnd+ RPAREN | lhsAnd (DRL_OR lhsAnd)* ;
-lhsAnd : LPAREN lhsAnd RPAREN | LPAREN DRL_AND lhsUnary+ RPAREN | lhsUnary 
(DRL_AND lhsUnary)* ;
+lhs : DRL_WHEN lhsExpression* ;
+
+lhsExpression : LPAREN lhsExpression RPAREN             #lhsExpressionEnclosed
+              | lhsUnary                                #lhsUnarySingle
+              | LPAREN DRL_AND lhsExpression+ RPAREN    #lhsAnd
+              | lhsExpression (DRL_AND lhsExpression)+  #lhsAnd
+              | LPAREN DRL_OR lhsExpression+ RPAREN     #lhsOr
+              | lhsExpression (DRL_OR lhsExpression)+   #lhsOr
+              ;
 
 /*
 lhsUnary : ( lhsExists namedConsequence?
@@ -57,6 +62,7 @@ lhsUnary : (
            | lhsNot
            | lhsPatternBind
            ) ;
+
 lhsPatternBind : label? ( LPAREN lhsPattern (DRL_OR lhsPattern)* RPAREN | 
lhsPattern ) ;
 
 /*
diff --git 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
index 7f69502301..22858fba9f 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
+++ 
b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java
@@ -186,17 +186,12 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
     @Override
     public List<BaseDescr> visitLhs(DRLParser.LhsContext ctx) {
         if (ctx.lhsExpression() != null) {
-            return visitLhsExpression(ctx.lhsExpression());
+            return visitDescrChildren(ctx);
         } else {
             return new ArrayList<>();
         }
     }
 
-    @Override
-    public List<BaseDescr> visitLhsExpression(DRLParser.LhsExpressionContext 
ctx) {
-        return visitDescrChildren(ctx);
-    }
-
     @Override
     public BaseDescr visitLhsPatternBind(DRLParser.LhsPatternBindContext ctx) {
         if (ctx.lhsPattern().size() == 1) {
@@ -294,33 +289,25 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
         return notDescr;
     }
 
+    @Override
+    public BaseDescr 
visitLhsExpressionEnclosed(DRLParser.LhsExpressionEnclosedContext ctx) {
+        return (BaseDescr) visit(ctx.lhsExpression());
+    }
+
     @Override
     public BaseDescr visitLhsOr(DRLParser.LhsOrContext ctx) {
-        if (!ctx.DRL_OR().isEmpty()) {
-            OrDescr orDescr = new OrDescr();
-            List<BaseDescr> descrList = visitDescrChildren(ctx);
-            descrList.forEach(orDescr::addDescr);
-            return orDescr;
-        } else {
-            // No DRL_OR means only one lhsAnd
-            return visitLhsAnd(ctx.lhsAnd().get(0));
-        }
+        OrDescr orDescr = new OrDescr();
+        List<BaseDescr> descrList = visitDescrChildren(ctx);
+        descrList.forEach(orDescr::addDescr);
+        return orDescr;
     }
 
     @Override
     public BaseDescr visitLhsAnd(DRLParser.LhsAndContext ctx) {
-        if (ctx.lhsAnd() != null) {
-            return visitLhsAnd(ctx.lhsAnd());
-        }
-        if (!ctx.DRL_AND().isEmpty()) {
-            AndDescr andDescr = new AndDescr();
-            List<BaseDescr> descrList = visitDescrChildren(ctx);
-            descrList.forEach(andDescr::addDescr);
-            return andDescr;
-        } else {
-            // No DRL_AND means only one lhsUnary
-            return visitLhsUnary(ctx.lhsUnary().get(0));
-        }
+        AndDescr andDescr = new AndDescr();
+        List<BaseDescr> descrList = visitDescrChildren(ctx);
+        descrList.forEach(andDescr::addDescr);
+        return andDescr;
     }
 
     @Override
diff --git 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
index dd88f61351..011926dc1b 100644
--- 
a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
+++ 
b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/MiscDRLParserTest.java
@@ -1389,22 +1389,21 @@ class MiscDRLParserTest {
         assertThat((String) 
rule.getConsequence()).isEqualToIgnoringWhitespace( "System.out.println( \"Mark 
and Michael\" + bar );");
     }
 
-    @Disabled("Priority : High | Failed to parse complex parentheses")
     @Test
-    public void parse_BracketsPrecedence() throws Exception {
+    void parenthesesOrAndOr() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
                                                                
"brackets_precedence.drl" );
 
-        assertThat(pkg.getRules().size()).isEqualTo(1);
+        assertThat(pkg.getRules()).hasSize(1);
         final RuleDescr rule = (RuleDescr) pkg.getRules().get( 0 );
 
         final AndDescr rootAnd = (AndDescr) rule.getLhs();
 
-        assertThat(rootAnd.getDescrs().size()).isEqualTo(2);
+        assertThat(rootAnd.getDescrs()).hasSize(2);
 
         final OrDescr leftOr = (OrDescr) rootAnd.getDescrs().get( 0 );
 
-        assertThat(leftOr.getDescrs().size()).isEqualTo(2);
+        assertThat(leftOr.getDescrs()).hasSize(2);
         final NotDescr not = (NotDescr) leftOr.getDescrs().get( 0 );
         final PatternDescr foo1 = (PatternDescr) not.getDescrs().get( 0 );
         assertThat(foo1.getObjectType()).isEqualTo("Foo");
@@ -1413,13 +1412,114 @@ class MiscDRLParserTest {
 
         final OrDescr rightOr = (OrDescr) rootAnd.getDescrs().get( 1 );
 
-        assertThat(rightOr.getDescrs().size()).isEqualTo(2);
+        assertThat(rightOr.getDescrs()).hasSize(2);
         final PatternDescr shoes = (PatternDescr) rightOr.getDescrs().get( 0 );
         assertThat(shoes.getObjectType()).isEqualTo("Shoes");
         final PatternDescr butt = (PatternDescr) rightOr.getDescrs().get( 1 );
         assertThat(butt.getObjectType()).isEqualTo("Butt");
     }
 
+    @Test
+    void parenthesesAndOrOr() {
+        final String drl = "rule and_or_or\n" +
+                "  when\n" +
+                "     (Foo(x == 1) and Bar(x == 2)) or (Foo(x == 3) or Bar(x 
== 4))\n" +
+                "  then\n" +
+                "end";
+        PackageDescr pkg = parser.parse(drl);
+
+        assertThat(pkg.getRules()).hasSize(1);
+        final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        final AndDescr rootAnd = (AndDescr) rule.getLhs();
+        assertThat(rootAnd.getDescrs()).hasSize(1);
+
+        final OrDescr topOr = (OrDescr) rootAnd.getDescrs().get(0);
+        assertThat(topOr.getDescrs()).hasSize(2);
+
+        final AndDescr leftAnd = (AndDescr) topOr.getDescrs().get(0);
+        assertThat(leftAnd.getDescrs()).hasSize(2);
+        final PatternDescr foo1 = (PatternDescr) leftAnd.getDescrs().get(0);
+        assertThat(foo1.getObjectType()).isEqualTo("Foo");
+        final PatternDescr bar1 = (PatternDescr) leftAnd.getDescrs().get(1);
+        assertThat(bar1.getObjectType()).isEqualTo("Bar");
+
+        final OrDescr rightOr = (OrDescr) topOr.getDescrs().get(1);
+        assertThat(rightOr.getDescrs()).hasSize(2);
+        final PatternDescr foo2 = (PatternDescr) rightOr.getDescrs().get(0);
+        assertThat(foo2.getObjectType()).isEqualTo("Foo");
+        final PatternDescr bar2 = (PatternDescr) rightOr.getDescrs().get(1);
+        assertThat(bar2.getObjectType()).isEqualTo("Bar");
+    }
+
+    @Test
+    void parenthesesOrAndAnd() {
+        final String drl = "rule or_and_and\n" +
+                "  when\n" +
+                "     (Foo(x == 1) or Bar(x == 2)) and (Foo(x == 3) and Bar(x 
== 4))\n" +
+                "  then\n" +
+                "end";
+        PackageDescr pkg = parser.parse(drl);
+
+        assertThat(pkg.getRules()).hasSize(1);
+        final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        final AndDescr rootAnd = (AndDescr) rule.getLhs();
+        assertThat(rootAnd.getDescrs()).hasSize(2);
+
+        final OrDescr leftOr = (OrDescr) rootAnd.getDescrs().get(0);
+        assertThat(leftOr.getDescrs()).hasSize(2);
+        final PatternDescr foo1 = (PatternDescr) leftOr.getDescrs().get(0);
+        assertThat(foo1.getObjectType()).isEqualTo("Foo");
+        final PatternDescr bar1 = (PatternDescr) leftOr.getDescrs().get(1);
+        assertThat(bar1.getObjectType()).isEqualTo("Bar");
+
+        final AndDescr rightAnd = (AndDescr) rootAnd.getDescrs().get(1);
+        assertThat(rightAnd.getDescrs()).hasSize(2);
+        final PatternDescr foo2 = (PatternDescr) rightAnd.getDescrs().get(0);
+        assertThat(foo2.getObjectType()).isEqualTo("Foo");
+        final PatternDescr bar2 = (PatternDescr) rightAnd.getDescrs().get(1);
+        assertThat(bar2.getObjectType()).isEqualTo("Bar");
+    }
+
+    @Test
+    void parenthesesAndOrOrOrAnd() throws Exception {
+        final String drl = "rule and_or_or_or_and\n" +
+                "  when\n" +
+                "     (Foo(x == 1) and (Bar(x == 2) or Foo(x == 3))) or (Bar(x 
== 4) or (Foo(x == 5) and Bar(x == 6)))\n" +
+                "  then\n" +
+                "end";
+        PackageDescr pkg = parser.parse(drl);
+
+        assertThat(pkg.getRules()).hasSize(1);
+        final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        final AndDescr rootAnd = (AndDescr) rule.getLhs();
+        assertThat(rootAnd.getDescrs()).hasSize(1);
+
+        final OrDescr topOr = (OrDescr) rootAnd.getDescrs().get(0);
+        assertThat(topOr.getDescrs()).hasSize(2);
+
+        final AndDescr leftAnd = (AndDescr) topOr.getDescrs().get(0);
+        assertThat(leftAnd.getDescrs()).hasSize(2);
+        final PatternDescr foo1 = (PatternDescr) leftAnd.getDescrs().get(0);
+        assertThat(foo1.getObjectType()).isEqualTo("Foo");
+        final OrDescr leftOr = (OrDescr) leftAnd.getDescrs().get(1);
+        assertThat(leftOr.getDescrs()).hasSize(2);
+        final PatternDescr bar1 = (PatternDescr) leftOr.getDescrs().get(0);
+        assertThat(bar1.getObjectType()).isEqualTo("Bar");
+        final PatternDescr foo2 = (PatternDescr) leftOr.getDescrs().get(1);
+        assertThat(foo2.getObjectType()).isEqualTo("Foo");
+
+        final OrDescr rightOr = (OrDescr) topOr.getDescrs().get(1);
+        assertThat(rightOr.getDescrs()).hasSize(2);
+        final PatternDescr bar2 = (PatternDescr) rightOr.getDescrs().get(0);
+        assertThat(bar2.getObjectType()).isEqualTo("Bar");
+        final AndDescr rightAnd = (AndDescr) rightOr.getDescrs().get(1);
+        assertThat(rightAnd.getDescrs()).hasSize(2);
+        final PatternDescr foo3 = (PatternDescr) rightAnd.getDescrs().get(0);
+        assertThat(foo3.getObjectType()).isEqualTo("Foo");
+        final PatternDescr bar3 = (PatternDescr) rightAnd.getDescrs().get(1);
+        assertThat(bar3.getObjectType()).isEqualTo("Bar");
+    }
+
     @Disabled("Priority : High | Implement eval")
     @Test
     public void parse_EvalMultiple() throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to