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 457fb1e44b2e14476b8d6329d484f7761a6ce0f5
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Mon Jun 27 15:42:21 2022 +0900

    Enhance test/grammar coverage. matches, single quoted string, escape (#9)
    
    - Introduced drlExpression, drlPrimary, drlLiteral, DRL_STRING_LITERAL
---
 .../src/main/antlr4/org/drools/parser/DRLLexer.g4  | 30 ++++++++
 .../src/main/antlr4/org/drools/parser/DRLParser.g4 | 79 ++++++++++++++++++----
 .../java/org/drools/parser/DRLVisitorImpl.java     | 15 +++-
 .../java/org/drools/parser/MiscDRLParserTest.java  | 61 +++++++++++++++++
 4 files changed, 168 insertions(+), 17 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 8ba1364c40..ed2416b6ac 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
@@ -39,6 +39,7 @@ EXISTS : 'exists';
 NOT : 'not';
 IN : 'in';
 FROM : 'from';
+MATCHES : 'matches';
 
 SALIENCE : 'salience';
 ENABLED : 'enabled';
@@ -69,6 +70,10 @@ TIME_INTERVAL
     | (('0'..'9')+ 'ms')
     ;
 
+DRL_STRING_LITERAL
+    :  ('"' ( DrlEscapeSequence | ~('\\'|'"') )* '"')
+    |  ('\'' ( DrlEscapeSequence | ~('\\'|'\'') )* '\'') { setText( 
normalizeString( getText() ) ); }
+    ;
 
 /////////////////
 // SYMBOLS
@@ -80,3 +85,28 @@ NULL_SAFE_DOT :      '!.' ;
 QUESTION_DIV : '?/' ;
 
 MISC : '\'' | '\\' | '$' ;
+
+/////////////////
+// Fragment
+/////////////////
+fragment
+DrlEscapeSequence
+    :   '\\' ('b'|'B'|'t'|'n'|'f'|'r'|'"'|'\''|'\\'|'.'|'o'|
+              'x'|'a'|'e'|'c'|'d'|'D'|'s'|'S'|'w'|'W'|'p'|'A'|
+              'G'|'Z'|'z'|'Q'|'E'|'*'|'['|']'|'('|')'|'$'|'^'|
+              '{'|'}'|'?'|'+'|'-'|'&'|'|')
+    |   DrlUnicodeEscape
+    |   DrlOctalEscape
+    ;
+
+fragment
+DrlOctalEscape
+    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
+    |   '\\' ('0'..'7') ('0'..'7')
+    |   '\\' ('0'..'7')
+    ;
+
+fragment
+DrlUnicodeEscape
+    :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit
+    ;
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 c9db7951aa..b68437835f 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
@@ -58,32 +58,83 @@ 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 : shiftExpression, 
additiveExpression, multiplicativeExpression, unaryExpression, 
unaryExpressionNotPlusMinus, ..., primary
+relationalExpression : drlExpression? ;
+
+/* extending JavaParser expression */
+drlExpression
+    : drlPrimary
+    | drlExpression bop=DOT
+      (
+         identifier
+       | methodCall
+       | THIS
+       | NEW nonWildcardTypeArguments? innerCreator
+       | SUPER superSuffix
+       | explicitGenericInvocation
+      )
+    | drlExpression LBRACK drlExpression RBRACK
+    | methodCall
+    | NEW creator
+    | LPAREN annotation* typeType (BITAND typeType)* RPAREN drlExpression
+    | drlExpression postfix=(INC | DEC)
+    | prefix=(ADD|SUB|INC|DEC) drlExpression
+    | prefix=(TILDE|BANG) drlExpression
+    | drlExpression bop=(MUL|DIV|MOD) drlExpression
+    | drlExpression bop=(ADD|SUB) drlExpression
+    | drlExpression (LT LT | GT GT GT | GT GT) drlExpression
+    | drlExpression bop=(LE | GE | GT | LT) drlExpression
+    | drlExpression bop=INSTANCEOF (typeType | pattern)
+    | drlExpression bop=MATCHES drlExpression
+    | drlExpression bop=(EQUAL | NOTEQUAL) drlExpression
+    | drlExpression bop=BITAND drlExpression
+    | drlExpression bop=CARET drlExpression
+    | drlExpression bop=BITOR drlExpression
+    | drlExpression bop=AND drlExpression
+    | drlExpression bop=OR drlExpression
+    | <assoc=right> drlExpression bop=QUESTION drlExpression COLON 
drlExpression
+    | <assoc=right> drlExpression
+      bop=(ASSIGN | ADD_ASSIGN | SUB_ASSIGN | MUL_ASSIGN | DIV_ASSIGN | 
AND_ASSIGN | OR_ASSIGN | XOR_ASSIGN | RSHIFT_ASSIGN | URSHIFT_ASSIGN | 
LSHIFT_ASSIGN | MOD_ASSIGN)
+      drlExpression
+    | lambdaExpression // Java8
+    | switchExpression // Java17
+
+    // Java 8 methodReference
+    | drlExpression COLONCOLON typeArguments? identifier
+    | typeType COLONCOLON (typeArguments? identifier | NEW)
+    | classType COLONCOLON typeArguments? NEW
+    ;
 
-/* extending JavaParser */
-primary
-    : LPAREN expression RPAREN
+/* extending JavaParser primary */
+drlPrimary
+    : LPAREN drlExpression RPAREN
     | THIS
     | SUPER
-    | literal
+    | drlLiteral
     | identifier
     | typeTypeOrVoid DOT CLASS
     | nonWildcardTypeArguments (explicitGenericInvocationSuffix | THIS 
arguments)
     | inlineListExpression
     ;
 
+/* extending JavaParser literal */
+drlLiteral
+    : integerLiteral
+    | floatLiteral
+    | CHAR_LITERAL
+    | DRL_STRING_LITERAL
+    | BOOL_LITERAL
+    | NULL_LITERAL
+    | TEXT_BLOCK // Java17
+    ;
+
 inlineListExpression
     :   LBRACK expressionList? RBRACK
     ;
 
 expressionList
-    :   expression (COMMA expression)*
+    :   drlExpression (COMMA drlExpression)*
     ;
 
-drlExpression : conditionalExpression ( op=assignmentOperator 
right=drlExpression )? ;
-conditionalExpression : left=conditionalOrExpression ternaryExpression? ;
-ternaryExpression : QUESTION ts=drlExpression COLON fs=drlExpression ;
-
 /*
  patternSource := FROM
                 ( fromAccumulate
@@ -112,9 +163,9 @@ lhsExists : EXISTS lhsPatternBind ;
 */
 lhsNot : NOT lhsPatternBind ;
 
-rhs : blockStatement+ ;
+rhs : blockStatement* ;
 
-stringId : ( IDENTIFIER | STRING_LITERAL ) ;
+stringId : ( IDENTIFIER | DRL_STRING_LITERAL ) ;
 
 type : IDENTIFIER typeArguments? ( DOT IDENTIFIER typeArguments? )* (LBRACK 
RBRACK)* ;
 
@@ -129,8 +180,8 @@ drlAnnotation : AT name=qualifiedName drlArguments? ;
 attributes : attribute ( COMMA? attribute )* ;
 attribute : ( 'salience' DECIMAL_LITERAL )
           | ( 'enabled' | 'no-loop' | 'auto-focus' | 'lock-on-active' | 
'refract' | 'direct' ) BOOL_LITERAL?
-          | ( 'agenda-group' | 'activation-group' | 'ruleflow-group' | 
'date-effective' | 'date-expires' | 'dialect' ) STRING_LITERAL
-          |   'calendars' STRING_LITERAL ( COMMA STRING_LITERAL )*
+          | ( 'agenda-group' | 'activation-group' | 'ruleflow-group' | 
'date-effective' | 'date-expires' | 'dialect' ) DRL_STRING_LITERAL
+          |   'calendars' DRL_STRING_LITERAL ( COMMA DRL_STRING_LITERAL )*
           |   'timer' ( DECIMAL_LITERAL | TEXT )
           |   'duration' ( DECIMAL_LITERAL | TEXT ) ;
 
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 98f6388b49..5706ddd9db 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
@@ -145,7 +145,16 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
     }
 
     @Override
-    public Object visitExpression(DRLParser.ExpressionContext ctx) {
+    public Object visitDrlExpression(DRLParser.DrlExpressionContext ctx) {
+        return ctx.children.stream()
+                .map(c -> c instanceof TerminalNode ? c : c.accept(this))
+                .filter(Objects::nonNull)
+                .map(Object::toString)
+                .collect(Collectors.joining(" "));
+    }
+
+    @Override
+    public Object visitDrlPrimary(DRLParser.DrlPrimaryContext ctx) {
         return ctx.children.stream()
                 .map(c -> c instanceof TerminalNode ? c : c.accept(this))
                 .filter(Objects::nonNull)
@@ -163,14 +172,14 @@ public class DRLVisitorImpl extends 
DRLParserBaseVisitor<Object> {
     }
 
     @Override
-    public Object visitLiteral(DRLParser.LiteralContext ctx) {
+    public Object visitDrlLiteral(DRLParser.DrlLiteralContext ctx) {
         ParseTree node = ctx;
         while (true) {
             if (node instanceof TerminalNode) {
                 return node.toString();
             }
             if (node.getChildCount() != 1) {
-                return super.visitLiteral(ctx);
+                return super.visitDrlLiteral(ctx);
             }
             node = node.getChild(0);
         }
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 07746c0299..c105a4a29f 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
@@ -13,6 +13,7 @@ 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.ExprConstraintDescr;
 import org.drools.drl.ast.descr.FromDescr;
 import org.drools.drl.ast.descr.FunctionImportDescr;
 import org.drools.drl.ast.descr.GlobalDescr;
@@ -397,4 +398,64 @@ public class MiscDRLParserTest extends TestCase {
                          ((PatternDescr) pdo2).getIdentifier());
         }
     }
+
+    @Test
+    public void testCompatibleRestriction() throws Exception {
+        String source = "package com.sample  rule test  when  Test( ( text == 
null || text2 matches \"\" ) )  then  end";
+        PackageDescr pkg = parser.parse(source);
+
+        assertEquals( "com.sample",
+                      pkg.getName() );
+        RuleDescr rule = (RuleDescr) pkg.getRules().get( 0 );
+        assertEquals( "test",
+                      rule.getName() );
+        ExprConstraintDescr expr = (ExprConstraintDescr) ((PatternDescr) 
rule.getLhs().getDescrs().get(0 )).getDescrs().get(0 );
+        assertEquals( "( text == null || text2 matches \"\" )",
+                      expr.getText() );
+    }
+
+    @Test
+    public void testSimpleConstraint() throws Exception {
+        String source = "package com.sample  rule test  when  Cheese( type == 
'stilton', price > 10 )  then  end";
+        PackageDescr pkg = parser.parse(source);
+
+        assertEquals( "com.sample",
+                      pkg.getName() );
+        RuleDescr rule = (RuleDescr) pkg.getRules().get( 0 );
+        assertEquals( "test",
+                      rule.getName() );
+
+        assertEquals( 1,
+                      rule.getLhs().getDescrs().size() );
+        PatternDescr pattern = (PatternDescr) rule.getLhs().getDescrs().get( 0 
);
+
+        AndDescr constraint = (AndDescr) pattern.getConstraint();
+        assertEquals( 2,
+                      constraint.getDescrs().size() );
+        assertEquals( "type == \"stilton\"",
+                      constraint.getDescrs().get( 0 ).toString() );
+        assertEquals( "price > 10",
+                      constraint.getDescrs().get( 1 ).toString() );
+    }
+
+    @Test
+    public void testStringEscapes() throws Exception {
+        String source = "package com.sample  rule test  when  Cheese( type 
matches \"\\..*\\\\.\" )  then  end";
+        PackageDescr pkg = parser.parse(source);
+        assertEquals( "com.sample",
+                      pkg.getName() );
+        RuleDescr rule = (RuleDescr) pkg.getRules().get( 0 );
+        assertEquals( "test",
+                      rule.getName() );
+
+        assertEquals( 1,
+                      rule.getLhs().getDescrs().size() );
+        PatternDescr pattern = (PatternDescr) rule.getLhs().getDescrs().get( 0 
);
+
+        AndDescr constraint = (AndDescr) pattern.getConstraint();
+        assertEquals( 1,
+                      constraint.getDescrs().size() );
+        assertEquals( "type matches \"\\..*\\\\.\"",
+                      constraint.getDescrs().get( 0 ).toString() );
+    }
 }


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

Reply via email to