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 f4ba08d700ee40e60f3c0ca567663df1df338971
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Wed Sep 20 17:01:07 2023 +0900

    [DROOLS-7289] Implement accumulate (#28)
---
 .../src/main/antlr4/org/drools/parser/DRLLexer.g4  |  5 ++
 .../src/main/antlr4/org/drools/parser/DRLParser.g4 | 47 +++++++++++++-
 .../java/org/drools/parser/DRLVisitorImpl.java     | 71 ++++++++++++++++++++--
 .../java/org/drools/parser/MiscDRLParserTest.java  | 12 +---
 4 files changed, 117 insertions(+), 18 deletions(-)

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 0e91fb3f2e..0eb6d961bc 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
@@ -44,6 +44,11 @@ DRL_NOT : 'not';
 DRL_IN : 'in';
 DRL_FROM : 'from';
 DRL_MATCHES : 'matches';
+DRL_ACCUMULATE : 'accumulate' | 'acc';
+DRL_INIT : 'init';
+DRL_ACTION : 'action';
+DRL_REVERSE : 'reverse';
+DRL_RESULT : 'result';
 
 DRL_SALIENCE : 'salience';
 DRL_ENABLED : 'enabled';
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 c150a480e4..1b96c788b3 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
@@ -46,6 +46,11 @@ lhsExpression : LPAREN lhsExpression RPAREN             
#lhsExpressionEnclosed
               | lhsExpression (DRL_OR lhsExpression)+   #lhsOr
               ;
 
+// and is accepted for accumulate
+lhsAndForAccumulate : lhsUnary (DRL_AND lhsUnary)+
+                    | LPAREN DRL_AND lhsUnary+ RPAREN
+                    ;
+
 /*
 lhsUnary : ( lhsExists namedConsequence?
            | lhsNot namedConsequence?
@@ -61,6 +66,7 @@ lhsUnary : (
            lhsExists
            | lhsNot
            | lhsPatternBind
+           | lhsAccumulate
            ) ;
 
 lhsPatternBind : label? ( LPAREN lhsPattern (DRL_OR lhsPattern)* RPAREN | 
lhsPattern ) ;
@@ -257,9 +263,35 @@ mapEntry
                 | fromWindow
                 | fromExpression )
 */
-patternSource : fromExpression ;
+patternSource : fromExpression
+              | fromAccumulate
+              ;
+
 fromExpression : conditionalOrExpression ;
 
+
+/*
+fromAccumulate := ACCUMULATE LEFT_PAREN lhsAnd (COMMA|SEMICOLON)
+                        ( INIT chunk_(_) COMMA ACTION chunk_(_) COMMA
+                          ( REVERSE chunk_(_) COMMA)? RESULT chunk_(_)
+                        | accumulateFunction
+                        ) RIGHT_PAREN
+*/
+fromAccumulate : DRL_ACCUMULATE LPAREN lhsAndForAccumulate (COMMA|SEMI)
+                   ( DRL_INIT LPAREN initBlockStatements=blockStatements 
RPAREN COMMA DRL_ACTION LPAREN actionBlockStatements=blockStatements RPAREN 
COMMA ( DRL_REVERSE LPAREN reverseBlockStatements=blockStatements RPAREN 
COMMA)? DRL_RESULT LPAREN expression RPAREN
+                   | accumulateFunction
+                   )
+                 RPAREN (SEMI)?
+                 ;
+
+blockStatements : blockStatement* ;
+
+/*
+accumulateFunction := label? ID parameters
+*/
+accumulateFunction : label? IDENTIFIER LPAREN drlExpression RPAREN;
+
+
 /*
  lhsExists := EXISTS
            ( (LEFT_PAREN (or_key|and_key))=> lhsOr  // prevents '((' for 
prefixed and/or
@@ -277,6 +309,19 @@ lhsExists : DRL_EXISTS lhsPatternBind ;
 */
 lhsNot : DRL_NOT lhsPatternBind ;
 
+/**
+ * lhsAccumulate := (ACCUMULATE|ACC) LEFT_PAREN lhsAnd (COMMA|SEMICOLON)
+ *                      accumulateFunctionBinding (COMMA 
accumulateFunctionBinding)*
+ *                      (SEMICOLON constraints)?
+ *                  RIGHT_PAREN SEMICOLON?
+ */
+
+lhsAccumulate : DRL_ACCUMULATE LPAREN lhsAndForAccumulate (COMMA|SEMI)
+                   accumulateFunction (COMMA accumulateFunction)*
+                   (SEMI constraints)?
+                 RPAREN (SEMI)?
+                 ;
+
 rhs : DRL_THEN consequence ;
 
 consequence : RHS_CHUNK* ;
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 22858fba9f..e3e5a499df 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
@@ -9,6 +9,7 @@ import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.TokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.RuleNode;
+import org.drools.drl.ast.descr.AccumulateDescr;
 import org.drools.drl.ast.descr.AndDescr;
 import org.drools.drl.ast.descr.AnnotationDescr;
 import org.drools.drl.ast.descr.AttributeDescr;
@@ -25,6 +26,7 @@ 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.PatternSourceDescr;
 import org.drools.drl.ast.descr.RuleDescr;
 import org.drools.drl.ast.descr.UnitDescr;
 
@@ -234,17 +236,66 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
     public PatternDescr visitLhsPattern(DRLParser.LhsPatternContext ctx) {
         PatternDescr patternDescr = 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(patternDescr.getResource());
-            patternDescr.setSource(from);
+            PatternSourceDescr patternSourceDescr = (PatternSourceDescr) 
visitPatternSource(ctx.patternSource());
+            patternSourceDescr.setResource(patternDescr.getResource());
+            patternDescr.setSource(patternSourceDescr);
         }
         List<ExprConstraintDescr> constraintDescrList = 
visitConstraints(ctx.constraints());
         constraintDescrList.forEach(patternDescr::addConstraint);
         return patternDescr;
     }
 
+    @Override
+    public PatternDescr visitLhsAccumulate(DRLParser.LhsAccumulateContext ctx) 
{
+        AccumulateDescr accumulateDescr = new AccumulateDescr();
+        
accumulateDescr.setInput(visitLhsAndForAccumulate(ctx.lhsAndForAccumulate()));
+
+        // accumulate function
+        for (DRLParser.AccumulateFunctionContext accumulateFunctionContext : 
ctx.accumulateFunction()) {
+            
accumulateDescr.addFunction(visitAccumulateFunction(accumulateFunctionContext));
+        }
+
+        PatternDescr patternDescr = new PatternDescr("Object");
+        patternDescr.setSource(accumulateDescr);
+        List<ExprConstraintDescr> constraintDescrList = 
visitConstraints(ctx.constraints());
+        constraintDescrList.forEach(patternDescr::addConstraint);
+        return patternDescr;
+    }
+
+    @Override
+    public FromDescr visitFromExpression(DRLParser.FromExpressionContext ctx) {
+        FromDescr fromDescr = new FromDescr();
+        fromDescr.setDataSource(new MVELExprDescr(ctx.getText()));
+        return fromDescr;
+    }
+
+    @Override
+    public AccumulateDescr visitFromAccumulate(DRLParser.FromAccumulateContext 
ctx) {
+        AccumulateDescr accumulateDescr = new AccumulateDescr();
+        
accumulateDescr.setInput(visitLhsAndForAccumulate(ctx.lhsAndForAccumulate()));
+        if (ctx.DRL_INIT() != null) {
+            // inline custom accumulate
+            
accumulateDescr.setInitCode(getTextPreservingWhitespace(ctx.initBlockStatements));
+            
accumulateDescr.setActionCode(getTextPreservingWhitespace(ctx.actionBlockStatements));
+            if (ctx.DRL_REVERSE() != null) {
+                
accumulateDescr.setReverseCode(getTextPreservingWhitespace(ctx.reverseBlockStatements));
+            }
+            accumulateDescr.setResultCode(ctx.expression().getText());
+        } else {
+            // accumulate function
+            
accumulateDescr.addFunction(visitAccumulateFunction(ctx.accumulateFunction()));
+        }
+        return accumulateDescr;
+    }
+
+    @Override
+    public AccumulateDescr.AccumulateFunctionCallDescr 
visitAccumulateFunction(DRLParser.AccumulateFunctionContext ctx) {
+        String function = ctx.IDENTIFIER().getText();
+        String bind = ctx.label() == null ? null : 
ctx.label().IDENTIFIER().getText();
+        String[] params = new 
String[]{getTextPreservingWhitespace(ctx.drlExpression())};
+        return new AccumulateDescr.AccumulateFunctionCallDescr(function, bind, 
false, params);
+    }
+
     @Override
     public List<ExprConstraintDescr> 
visitConstraints(DRLParser.ConstraintsContext ctx) {
         if (ctx == null) {
@@ -304,12 +355,20 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
 
     @Override
     public BaseDescr visitLhsAnd(DRLParser.LhsAndContext ctx) {
+        return createAndDescr(visitDescrChildren(ctx));
+    }
+
+    private AndDescr createAndDescr(List<BaseDescr> descrList) {
         AndDescr andDescr = new AndDescr();
-        List<BaseDescr> descrList = visitDescrChildren(ctx);
         descrList.forEach(andDescr::addDescr);
         return andDescr;
     }
 
+    @Override
+    public BaseDescr 
visitLhsAndForAccumulate(DRLParser.LhsAndForAccumulateContext ctx) {
+        return createAndDescr(visitDescrChildren(ctx));
+    }
+
     @Override
     public BaseDescr visitLhsUnary(DRLParser.LhsUnaryContext ctx) {
         return (BaseDescr) visitChildren(ctx);
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 011926dc1b..96134e5ee2 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
@@ -305,7 +305,6 @@ class MiscDRLParserTest {
                 " System.err.println(\"Invalid customer id found!\"); \n" +
                 " o.addError(\"Invalid customer id\"); \n" +
                 "end \n";
-        System.out.println(source);
         PackageDescr pkg = parser.parse(source);
         
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();
 
@@ -2011,7 +2010,6 @@ class MiscDRLParserTest {
         assertThat(p.getObjectType()).isEqualTo("com.cheeseco.Cheese");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_Accumulate() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2034,7 +2032,6 @@ class MiscDRLParserTest {
         assertThat(pattern.getObjectType()).isEqualTo("Person");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateWithBindings() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2356,7 +2353,6 @@ class MiscDRLParserTest {
         assertThat(rule1.getLhs().getDescrs().size()).isEqualTo(1);
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateReverse() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2382,7 +2378,6 @@ class MiscDRLParserTest {
         assertThat(pattern.getObjectType()).isEqualTo("Person");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateExternalFunction() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2426,7 +2421,7 @@ class MiscDRLParserTest {
         assertThat(people.getObjectType()).isEqualTo("People");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
+    @Disabled("Priority : High | Implement accumulate and Implement from 
collect")
     @Test
     public void parse_AccumulateWithNestedFrom() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2448,7 +2443,6 @@ class MiscDRLParserTest {
         assertThat(people.getObjectType()).isEqualTo("People");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateMultipleFunctions() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2482,7 +2476,6 @@ class MiscDRLParserTest {
         assertThat(pattern.getObjectType()).isEqualTo("Cheese");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateMnemonic() throws Exception {
         String drl = "package org.drools.mvel.compiler\n" +
@@ -2515,7 +2508,6 @@ class MiscDRLParserTest {
         assertThat(pattern.getObjectType()).isEqualTo("Cheese");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateMnemonic2() throws Exception {
         String drl = "package org.drools.mvel.compiler\n" +
@@ -2596,7 +2588,6 @@ class MiscDRLParserTest {
         assertThat(pattern.getObjectType()).isEqualTo("Cheese");
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateMultipleFunctionsConstraint() throws Exception 
{
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(
@@ -2701,7 +2692,6 @@ class MiscDRLParserTest {
 
     }
 
-    @Disabled("Priority : High | Implement accumulate")
     @Test
     public void parse_AccumulateMultiPattern() throws Exception {
         final PackageDescr pkg = parseAndGetPackageDescrFromFile(


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

Reply via email to