From 4818e196414baaf64cf727baad3923845c213647 Mon Sep 17 00:00:00 2001 From: Toshiya Kobayashi Date: Thu, 23 May 2024 11:27:42 +0900 Subject: [PATCH] [incubator-kie-drools-5936] [new-parser] || and && should be allowed as alternatives to infix or and and (#5966) --- .../drl/parser/antlr4/MiscDRLParserTest.java | 78 ++++++++++++++++++- .../org/drools/drl/parser/antlr4/DRLParser.g4 | 10 +-- .../antlr4/Antlr4ParserStringUtils.java | 6 ++ .../drl/parser/antlr4/DRLVisitorImpl.java | 2 +- 4 files changed, 88 insertions(+), 8 deletions(-) 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 ca565a83209..e81bfb21f0c 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 @@ -5135,11 +5135,85 @@ void accumulateEmptyChunks() { "end"; RuleDescr rule = parseAndGetFirstRuleDescr(text); - final PatternDescr outPattern = (PatternDescr) rule.getLhs().getDescrs().get( 0 ); + final PatternDescr outPattern = (PatternDescr) rule.getLhs().getDescrs().get(0); final AccumulateDescr accumulateDescr = (AccumulateDescr) outPattern.getSource(); assertThat(accumulateDescr.getInitCode()).isEmpty(); assertThat(accumulateDescr.getActionCode()).isEmpty(); assertThat(accumulateDescr.getReverseCode()).isNull(); - assertThat(accumulateDescr.getResultCode()).isEqualTo( "null"); + assertThat(accumulateDescr.getResultCode()).isEqualTo("null"); + } + + @Test + void doublePipeInfixOr() { + final String text = + "rule R\n" + + "when\n" + + " Person()\n" + + " ||\n" + + " Address()\n" + + "then\n" + + "end"; + RuleDescr rule = parseAndGetFirstRuleDescr(text); + assertThat(rule.getLhs().getDescrs().get(0)).isInstanceOfSatisfying(OrDescr.class, orDescr -> { + assertThat(orDescr.getDescrs().get(0)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("Person"); + }); + assertThat(orDescr.getDescrs().get(1)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("Address"); + }); + }); + } + + @Test + void doubleAmpersandInfixAnd() { + final String text = + "rule R\n" + + "when\n" + + " Person()\n" + + " &&\n" + + " Address()\n" + + "then\n" + + "end"; + RuleDescr rule = parseAndGetFirstRuleDescr(text); + assertThat(rule.getLhs().getDescrs().get(0)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("Person"); + }); + assertThat(rule.getLhs().getDescrs().get(1)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("Address"); + }); + } + + @Test + void doubleAmpersandInfixAndInAccumulate() { + final String text = + "rule R\n" + + "when\n" + + " accumulate( FactA($a : value) && FactB($b : value);\n" + + " $avg : average($a + $b))\n" + + "then\n" + + "end"; + RuleDescr rule = parseAndGetFirstRuleDescr(text); + final PatternDescr outPattern = (PatternDescr) rule.getLhs().getDescrs().get(0); + AccumulateDescr accumulateDescr = (AccumulateDescr) outPattern.getSource(); + assertThat(accumulateDescr.getInput()).isInstanceOfSatisfying(AndDescr.class, andDescr -> { + assertThat(andDescr.getDescrs()).hasSize(2); + assertThat(andDescr.getDescrs().get(0)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("FactA"); + assertThat(patternDescr.getConstraint().getDescrs().get(0)).isInstanceOfSatisfying(ExprConstraintDescr.class, exprConstraintDescr -> { + assertThat(exprConstraintDescr.getExpression()).isEqualTo("$a : value"); + }); + }); + assertThat(andDescr.getDescrs().get(1)).isInstanceOfSatisfying(PatternDescr.class, patternDescr -> { + assertThat(patternDescr.getObjectType()).isEqualTo("FactB"); + assertThat(patternDescr.getConstraint().getDescrs().get(0)).isInstanceOfSatisfying(ExprConstraintDescr.class, exprConstraintDescr -> { + assertThat(exprConstraintDescr.getExpression()).isEqualTo("$b : value"); + }); + }); + }); + + AccumulateDescr.AccumulateFunctionCallDescr accumulateFunction = accumulateDescr.getFunctions().get(0); + assertThat(accumulateFunction.getBind()).isEqualTo("$avg"); + assertThat(accumulateFunction.getFunction()).isEqualTo("average"); + assertThat(accumulateFunction.getParams()).containsExactly("$a + $b"); } } 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 e96aa729aec..251f73f2508 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 @@ -104,16 +104,16 @@ lhs : DRL_WHEN lhsExpression* ; queryLhs : lhsExpression* ; lhsExpression : LPAREN lhsExpression RPAREN #lhsExpressionEnclosed - | lhsUnary #lhsUnarySingle - | DRL_AND drlAnnotation* lhsExpression+ #lhsAnd - | lhsExpression (DRL_AND drlAnnotation* lhsExpression)+ #lhsAnd | DRL_OR drlAnnotation* lhsExpression+ #lhsOr - | lhsExpression (DRL_OR drlAnnotation* lhsExpression)+ #lhsOr + | lhsExpression ((DRL_OR|OR) drlAnnotation* lhsExpression)+ #lhsOr + | DRL_AND drlAnnotation* lhsExpression+ #lhsAnd + | lhsExpression ((DRL_AND|AND) drlAnnotation* lhsExpression)+ #lhsAnd + | lhsUnary #lhsUnarySingle ; // lhsAnd is used as a label in lhsExpression rule. But some other rules explicitly use the def, so lhsAndDef is declared. lhsAndDef : LPAREN lhsAndDef RPAREN - | lhsUnary (DRL_AND lhsUnary)* + | lhsUnary ((DRL_AND|AND) lhsUnary)* | LPAREN DRL_AND lhsUnary+ RPAREN ; diff --git a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Antlr4ParserStringUtils.java b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Antlr4ParserStringUtils.java index a0f09fb4717..74fb54c2c4c 100644 --- a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Antlr4ParserStringUtils.java +++ b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Antlr4ParserStringUtils.java @@ -56,6 +56,9 @@ public static String getTextPreservingWhitespace(ParserRuleContext ctx) { * Get text from List of ParserRuleContext's CharStream without trimming whitespace */ public static String getTextPreservingWhitespace(List ctx) { + if (ctx == null) { + return ""; + } return ctx.stream().map(Antlr4ParserStringUtils::getTextPreservingWhitespace).collect(Collectors.joining()); } @@ -65,6 +68,9 @@ public static String getTextPreservingWhitespace(List