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 37185cf825775b9c73c9172028b9c64747de1fe7
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Sun May 29 16:34:48 2022 +0900

    Enhance test/grammar coverage. and, or, listExpression (#7)
---
 drools-drl/drools-drl10-parser/pom.xml             |   6 ++
 .../src/main/antlr4/org/drools/parser/DRLLexer.g4  |   3 +
 .../src/main/antlr4/org/drools/parser/DRLParser.g4 |  28 ++++-
 .../java/org/drools/parser/DRLVisitorImpl.java     |  52 ++++++---
 .../java/org/drools/parser/MiscDRLParserTest.java  | 120 +++++++++++++++++++++
 5 files changed, 192 insertions(+), 17 deletions(-)

diff --git a/drools-drl/drools-drl10-parser/pom.xml 
b/drools-drl/drools-drl10-parser/pom.xml
index 599ec8ab07..93eefbc5d0 100644
--- a/drools-drl/drools-drl10-parser/pom.xml
+++ b/drools-drl/drools-drl10-parser/pom.xml
@@ -47,6 +47,12 @@
       <version>${version.junit}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>${version.org.assertj}</version>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
diff --git 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
index 0f4ee3cc48..8ba1364c40 100644
--- 
a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
+++ 
b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4
@@ -32,6 +32,9 @@ WHEN : 'when';
 THEN : 'then';
 END : 'end';
 
+KWD_AND : 'and';
+KWD_OR : 'or';
+
 EXISTS : 'exists';
 NOT : 'not';
 IN : 'in';
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 2818590bd5..c9db7951aa 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
@@ -19,8 +19,8 @@ ruledef : RULE name=stringId (EXTENDS stringId)? 
drlAnnotation* attributes? WHEN
 
 lhs : lhsExpression ;
 lhsExpression : lhsOr* ;
-lhsOr : LPAREN OR lhsAnd+ RPAREN | lhsAnd (OR lhsAnd)* ;
-lhsAnd : LPAREN AND lhsUnary+ RPAREN | lhsUnary (AND lhsUnary)* ;
+lhsOr : LPAREN KWD_OR lhsAnd+ RPAREN | lhsAnd (KWD_OR lhsAnd)* ;
+lhsAnd : LPAREN KWD_AND lhsUnary+ RPAREN | lhsUnary (KWD_AND lhsUnary)* ;
 
 /*
 lhsUnary : ( lhsExists namedConsequence?
@@ -38,7 +38,7 @@ lhsUnary : (
            | lhsNot
            | lhsPatternBind
            ) ;
-lhsPatternBind : label? ( LPAREN lhsPattern (OR lhsPattern)* RPAREN | 
lhsPattern ) ;
+lhsPatternBind : label? ( LPAREN lhsPattern (KWD_OR lhsPattern)* RPAREN | 
lhsPattern ) ;
 
 /*
 lhsPattern : xpathPrimary (OVER patternFilter)? |
@@ -58,7 +58,27 @@ andExpression : left=equalityExpression (BITAND 
right=equalityExpression)* ;
 equalityExpression : left=instanceOfExpression ( ( op=EQUAL | op=NOTEQUAL ) 
right=instanceOfExpression )* ;
 instanceOfExpression : left=inExpression ( 'instanceof' right=type )? ;
 inExpression : left=relationalExpression ( 'not'? 'in' LPAREN drlExpression 
(COMMA drlExpression)* RPAREN )? ;
-relationalExpression : expression? ; // TODO
+relationalExpression : expression? ; // TODO : shiftExpression, 
additiveExpression, multiplicativeExpression, unaryExpression, 
unaryExpressionNotPlusMinus, ..., primary
+
+/* extending JavaParser */
+primary
+    : LPAREN expression RPAREN
+    | THIS
+    | SUPER
+    | literal
+    | identifier
+    | typeTypeOrVoid DOT CLASS
+    | nonWildcardTypeArguments (explicitGenericInvocationSuffix | THIS 
arguments)
+    | inlineListExpression
+    ;
+
+inlineListExpression
+    :   LBRACK expressionList? RBRACK
+    ;
+
+expressionList
+    :   expression (COMMA expression)*
+    ;
 
 drlExpression : conditionalExpression ( op=assignmentOperator 
right=drlExpression )? ;
 conditionalExpression : left=conditionalOrExpression ternaryExpression? ;
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 d93c707abe..98f6388b49 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
@@ -2,6 +2,7 @@ package org.drools.parser;
 
 import java.util.ArrayDeque;
 import java.util.Deque;
+import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
@@ -19,7 +20,8 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     private RuleDescr currentRule;
     private PatternDescr currentPattern;
-    private Deque<ConditionalElementDescr> currentConstructStack = new 
ArrayDeque<>(); // e.g. whole LHS, not, exist
+
+    private final Deque<ConditionalElementDescr> currentConstructStack = new 
ArrayDeque<>(); // e.g. whole LHS (= AndDescr), NotDescr, ExistsDescr
 
     @Override
     public Object visitCompilationUnit(DRLParser.CompilationUnitContext ctx) {
@@ -86,23 +88,47 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     @Override
     public Object visitLhsPatternBind(DRLParser.LhsPatternBindContext ctx) {
-        // TODO: this logic will likely be split to visitLhsPattern
         if (ctx.lhsPattern().size() == 1) {
-            DRLParser.LhsPatternContext lhsPatternCtx = ctx.lhsPattern(0);
-            currentPattern = new 
PatternDescr(lhsPatternCtx.objectType.getText());
+            Object result = super.visitLhsPatternBind(ctx);
+            PatternDescr patternDescr = (PatternDescr) 
currentConstructStack.peek().getDescrs().get(0);
             if (ctx.label() != null) {
-                
currentPattern.setIdentifier(ctx.label().IDENTIFIER().getText());
+                patternDescr.setIdentifier(ctx.label().IDENTIFIER().getText());
             }
-            if (lhsPatternCtx.patternSource() != null) {
-                String expression = lhsPatternCtx.patternSource().getText();
-                FromDescr from = new FromDescr();
-                from.setDataSource(new MVELExprDescr(expression));
-                from.setResource(currentPattern.getResource());
-                currentPattern.setSource(from);
+            return result;
+        } else if (ctx.lhsPattern().size() > 1) {
+            OrDescr orDescr = new OrDescr();
+            currentConstructStack.peek().addDescr(orDescr);
+            currentConstructStack.push(orDescr);
+            try {
+                Object result = super.visitLhsPatternBind(ctx);
+                List<? extends BaseDescr> descrs = orDescr.getDescrs();
+                for (BaseDescr descr : descrs) {
+                    PatternDescr patternDescr = (PatternDescr) descr;
+                    if (ctx.label() != null) {
+                        
patternDescr.setIdentifier(ctx.label().IDENTIFIER().getText());
+                    }
+                }
+                return result;
+            } finally {
+                currentConstructStack.pop();
             }
-            currentConstructStack.peek().addDescr(currentPattern);
+        } else {
+            throw new IllegalStateException("ctx.lhsPattern().size() == 0 : " 
+ ctx.getText());
+        }
+    }
+
+    @Override
+    public Object visitLhsPattern(DRLParser.LhsPatternContext ctx) {
+        currentPattern = new PatternDescr(ctx.objectType.getText());
+        if (ctx.patternSource() != null) {
+            String expression = ctx.patternSource().getText();
+            FromDescr from = new FromDescr();
+            from.setDataSource(new MVELExprDescr(expression));
+            from.setResource(currentPattern.getResource());
+            currentPattern.setSource(from);
         }
-        Object result = super.visitLhsPatternBind(ctx);
+        Object result = super.visitLhsPattern(ctx);
+            currentConstructStack.peek().addDescr(currentPattern);
         currentPattern = null;
         return result;
     }
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 caabed1592..07746c0299 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
@@ -10,11 +10,15 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 
 import junit.framework.TestCase;
+import org.assertj.core.api.Assertions;
+import org.drools.drl.ast.descr.AndDescr;
+import org.drools.drl.ast.descr.BaseDescr;
 import org.drools.drl.ast.descr.FromDescr;
 import org.drools.drl.ast.descr.FunctionImportDescr;
 import org.drools.drl.ast.descr.GlobalDescr;
 import org.drools.drl.ast.descr.ImportDescr;
 import org.drools.drl.ast.descr.NotDescr;
+import org.drools.drl.ast.descr.OrDescr;
 import org.drools.drl.ast.descr.PackageDescr;
 import org.drools.drl.ast.descr.PatternDescr;
 import org.drools.drl.ast.descr.RuleDescr;
@@ -22,6 +26,8 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 /*
  * This test class is being ported from 
org.drools.mvel.compiler.lang.RuleParserTest
  */
@@ -277,4 +283,118 @@ public class MiscDRLParserTest extends TestCase {
         assertEquals("customerService.getCustomer(o.getCustomerId())",
                      ((FromDescr) 
customer.getSource()).getDataSource().getText());
     }
+
+    @Test
+    public void testFromWithInlineList() throws Exception {
+        String source = "rule XYZ \n" +
+                " when \n" +
+                " o: Order( ) \n" +
+                " not( Number( ) from [1, 2, 3] ) \n" +
+                " then \n" +
+                " System.err.println(\"Invalid customer id found!\"); \n" +
+                " o.addError(\"Invalid customer id\"); \n" +
+                "end \n";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+
+        RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        assertEquals("XYZ",
+                     rule.getName());
+
+        PatternDescr number = (PatternDescr) ((NotDescr) 
rule.getLhs().getDescrs().get(1)).getDescrs().get(0);
+        assertThat(((FromDescr) 
number.getSource()).getDataSource().toString()).isEqualToIgnoringWhitespace("[1,
 2, 3]");
+    }
+
+    @Test
+    public void testFromWithInlineListMethod() throws Exception {
+        String source = "rule XYZ \n" +
+                " when \n" +
+                " o: Order( ) \n" +
+                " Number( ) from [1, 2, 3].sublist(1, 2) \n" +
+                " then \n" +
+                " System.err.println(\"Invalid customer id found!\"); \n" +
+                " o.addError(\"Invalid customer id\"); \n" +
+                "end \n";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+
+        RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        assertEquals("XYZ",
+                     rule.getName());
+
+        assertFalse(parser.hasErrors());
+        PatternDescr number = (PatternDescr) rule.getLhs().getDescrs().get(1);
+
+        assertThat(((FromDescr) 
number.getSource()).getDataSource().toString()).isEqualToIgnoringWhitespace("[1,
 2, 3].sublist(1, 2)");
+    }
+
+    @Test
+    public void testFromWithInlineListIndex() throws Exception {
+        String source = "rule XYZ \n" +
+                " when \n" +
+                " o: Order( ) \n" +
+                " Number( ) from [1, 2, 3][1] \n" +
+                " then \n" +
+                " System.err.println(\"Invalid customer id found!\"); \n" +
+                " o.addError(\"Invalid customer id\"); \n" +
+                "end \n";
+        PackageDescr pkg = parser.parse(source);
+
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+
+        RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
+        assertEquals("XYZ",
+                     rule.getName());
+
+        assertFalse(parser.hasErrors());
+        PatternDescr number = (PatternDescr) rule.getLhs().getDescrs().get(1);
+        assertThat(((FromDescr) 
number.getSource()).getDataSource().toString()).isEqualToIgnoringWhitespace("[1,
 2, 3][1]");
+    }
+
+    @Test
+    public void testRuleWithoutEnd() throws Exception {
+        String source = "rule \"Invalid customer id\" \n" +
+                " when \n" +
+                " o: Order( ) \n" +
+                " then \n" +
+                " System.err.println(\"Invalid customer id found!\"); \n";
+        parser.parse(source);
+        assertTrue(parser.hasErrors());
+    }
+
+    @Test
+    public void testOrWithSpecialBind() throws Exception {
+        String source = "rule \"A and (B or C or D)\" \n" +
+                "    when \n" +
+                "        pdo1 : ParametricDataObject( paramID == 101, 
stringValue == \"1000\" ) and \n" +
+                "        pdo2 :(ParametricDataObject( paramID == 101, 
stringValue == \"1001\" ) or \n" +
+                "               ParametricDataObject( paramID == 101, 
stringValue == \"1002\" ) or \n" +
+                "               ParametricDataObject( paramID == 101, 
stringValue == \"1003\" )) \n" +
+                "    then \n" +
+                "        System.out.println( \"Rule: A and (B or C or D) 
Fired. pdo1: \" + pdo1 +  \" pdo2: \"+ pdo2); \n" +
+                "end\n";
+        PackageDescr pkg = parser.parse(source);
+        assertFalse(parser.getErrors().toString(),
+                    parser.hasErrors());
+
+        RuleDescr rule = pkg.getRules().get(0);
+        AndDescr lhs = rule.getLhs();
+        assertEquals(2,
+                     lhs.getDescrs().size());
+
+        PatternDescr pdo1 = (PatternDescr) lhs.getDescrs().get(0);
+        assertEquals("pdo1",
+                     pdo1.getIdentifier());
+
+        OrDescr or = (OrDescr) rule.getLhs().getDescrs().get(1);
+        assertEquals(3,
+                     or.getDescrs().size());
+        for (BaseDescr pdo2 : or.getDescrs()) {
+            assertEquals("pdo2",
+                         ((PatternDescr) pdo2).getIdentifier());
+        }
+    }
 }


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

Reply via email to