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 8827fb5184f40b4bd9a65a4f17ef5c57787b4d91 Author: Toshiya Kobayashi <[email protected]> AuthorDate: Wed Oct 18 23:04:31 2023 +0900 [DROOLS-7305] Implement type declaration (#40) - also covers [DROOLS-7291] Implement entry-point declaration - also covers window declaration --- .../src/main/antlr4/org/drools/parser/DRLLexer.g4 | 8 ++- .../src/main/antlr4/org/drools/parser/DRLParser.g4 | 67 +++++++++++++++--- .../java/org/drools/parser/DRLVisitorImpl.java | 81 +++++++++++++++++++++- .../java/org/drools/parser/MiscDRLParserTest.java | 4 -- 4 files changed, 141 insertions(+), 19 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 35bfe12f99..cce083ab8a 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 @@ -35,7 +35,7 @@ DRL_RULE : 'rule'; DRL_QUERY : 'query'; DRL_WHEN : 'when'; DRL_THEN : 'then' -> pushMode(RHS); -DRL_QUERY_END : 'end'; +DRL_END : 'end'; DRL_AND : 'and'; DRL_OR : 'or'; @@ -47,7 +47,8 @@ DRL_FROM : 'from'; DRL_COLLECT : 'collect'; DRL_MATCHES : 'matches'; DRL_MEMBEROF : 'memberOf'; -DRL_ACCUMULATE : 'accumulate' | 'acc'; +DRL_ACCUMULATE : 'accumulate'; +DRL_ACC : 'acc'; DRL_INIT : 'init'; DRL_ACTION : 'action'; DRL_REVERSE : 'reverse'; @@ -72,6 +73,7 @@ DRL_OVERLAPPED_BY : 'overlappedby'; DRL_STARTS : 'starts'; DRL_STARTED_BY : 'startedby'; +DRL_WINDOW : 'window'; // attributes DRL_SALIENCE : 'salience'; @@ -155,5 +157,5 @@ DrlUnicodeEscape mode RHS; RHS_WS : [ \t\r\n\u000C]+ -> channel(HIDDEN); -DRL_END : 'end' [ \t]* SEMI? [ \t]* ('\n' | '\r\n' | EOF) {setText("end");} -> popMode; +DRL_RHS_END : 'end' [ \t]* SEMI? [ \t]* ('\n' | '\r\n' | EOF) {setText("end");} -> popMode; RHS_CHUNK : ~[ \t\r\n\u000C]+ ; 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 6069196f7c..30ba8454cc 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,6 +19,7 @@ compilationUnit : packagedef? unitdef? drlStatementdef* ; drlStatementdef : importdef | globaldef + | declaredef | ruledef | attributes | functiondef @@ -29,19 +30,56 @@ packagedef : PACKAGE name=drlQualifiedName SEMI? ; unitdef : DRL_UNIT name=drlQualifiedName SEMI? ; -importdef : IMPORT (DRL_FUNCTION|STATIC)? drlQualifiedName (DOT MUL)? SEMI? #importStandardDef - | IMPORT DRL_ACCUMULATE drlQualifiedName IDENTIFIER SEMI? #importAccumulateDef +importdef : IMPORT (DRL_FUNCTION|STATIC)? drlQualifiedName (DOT MUL)? SEMI? #importStandardDef + | IMPORT (DRL_ACCUMULATE|DRL_ACC) drlQualifiedName IDENTIFIER SEMI? #importAccumulateDef ; globaldef : DRL_GLOBAL type drlIdentifier SEMI? ; +/** + * declare := DECLARE + * | (ENTRY-POINT) => entryPointDeclaration + * | (WINDOW) => windowDeclaration + * | (TRAIT) => typeDeclaration (trait) + * | (ENUM) => enumDeclaration + * | typeDeclaration (class) + * END + */ + +declaredef : DRL_DECLARE ( + | entryPointDeclaration + | windowDeclaration + | typeDeclaration + ) DRL_END ; + +/* + * typeDeclaration := [TYPE] qualifiedIdentifier (EXTENDS qualifiedIdentifier)? + * annotation* + * field* + * END + */ + +typeDeclaration : name=drlQualifiedName (EXTENDS superType=drlQualifiedName)? drlAnnotation* field* ; + +// entryPointDeclaration := ENTRY-POINT stringId annotation* END + +entryPointDeclaration : DRL_ENTRY_POINT name=stringId drlAnnotation* ; + +// windowDeclaration := WINDOW ID annotation* lhsPatternBind END + +windowDeclaration : DRL_WINDOW name=stringId drlAnnotation* lhsPatternBind ; + +// field := label fieldType (EQUALS_ASSIGN conditionalExpression)? annotation* SEMICOLON? + +field : label type (ASSIGN initExpr=conditionalOrExpression)? drlAnnotation* SEMI? ; + // rule := RULE stringId (EXTENDS stringId)? annotation* attributes? lhs? rhs END -ruledef : DRL_RULE name=stringId (EXTENDS parentName=stringId)? drlAnnotation* attributes? lhs rhs DRL_END ; +ruledef : DRL_RULE name=stringId (EXTENDS parentName=stringId)? drlAnnotation* attributes? lhs rhs DRL_RHS_END ; // query := QUERY stringId parameters? annotation* lhsExpression END -querydef : DRL_QUERY name=stringId formalParameters? drlAnnotation* lhsExpression+ DRL_QUERY_END SEMI?; +querydef : DRL_QUERY name=stringId formalParameters? drlAnnotation* lhsExpression+ DRL_END SEMI?; lhs : DRL_WHEN lhsExpression* ; @@ -152,7 +190,7 @@ drlKeywords | DRL_QUERY | DRL_WHEN | DRL_THEN - | DRL_QUERY_END + | DRL_END | DRL_AND | DRL_OR | DRL_EXISTS @@ -162,6 +200,7 @@ drlKeywords | DRL_MATCHES | DRL_MEMBEROF | DRL_ACCUMULATE + | DRL_ACC | DRL_INIT | DRL_ACTION | DRL_REVERSE @@ -287,7 +326,7 @@ mapEntry patternFilter := OVER filterDef filterDef := label ID LEFT_PAREN parameters RIGHT_PAREN */ -patternFilter : label IDENTIFIER LPAREN expressionList RPAREN ; +patternFilter : DRL_WINDOW COLON IDENTIFIER LPAREN expressionList RPAREN ; /* patternSource := FROM @@ -313,7 +352,7 @@ fromAccumulate := ACCUMULATE LEFT_PAREN lhsAnd (COMMA|SEMICOLON) | accumulateFunction ) RIGHT_PAREN */ -fromAccumulate : DRL_ACCUMULATE LPAREN lhsAndDef (COMMA|SEMI) +fromAccumulate : (DRL_ACCUMULATE|DRL_ACC) LPAREN lhsAndDef (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 ) @@ -368,7 +407,7 @@ lhsForall : DRL_FORALL LPAREN lhsPatternBind+ RPAREN ; * RIGHT_PAREN SEMICOLON? */ -lhsAccumulate : DRL_ACCUMULATE LPAREN lhsAndDef (COMMA|SEMI) +lhsAccumulate : (DRL_ACCUMULATE|DRL_ACC) LPAREN lhsAndDef (COMMA|SEMI) accumulateFunction (COMMA accumulateFunction)* (SEMI constraints)? RPAREN (SEMI)? @@ -380,7 +419,7 @@ consequence : RHS_CHUNK* ; stringId : ( IDENTIFIER | DRL_STRING_LITERAL ) ; -type : IDENTIFIER typeArguments? ( DOT IDENTIFIER typeArguments? )* (LBRACK RBRACK)* ; +type : (classOrInterfaceType | primitiveType) typeArguments? ( DOT IDENTIFIER typeArguments? )* (LBRACK RBRACK)* ; //typeArguments : LT typeArgument (COMMA typeArgument)* GT ; //typeArgument : QUESTION (( EXTENDS | SUPER ) type )? | type ; @@ -388,7 +427,15 @@ type : IDENTIFIER typeArguments? ( DOT IDENTIFIER typeArguments? )* (LBRACK RBRA drlArguments : LPAREN drlArgument (COMMA drlArgument)* RPAREN ; drlArgument : ( stringId | floatLiteral | BOOL_LITERAL | NULL_LITERAL ) ; -drlAnnotation : AT name=drlQualifiedName drlArguments? ; +drlAnnotation : AT name=drlQualifiedName (LPAREN ( drlElementValuePairs | drlElementValue )? RPAREN)? ; + +drlElementValuePairs : drlElementValuePair (COMMA drlElementValuePair)* ; +drlElementValuePair : key=drlIdentifier ASSIGN value=drlElementValue ; + +drlElementValue + : drlExpression + | drlArrayInitializer + ; attributes : attribute ( COMMA? attribute )* ; attribute : ( 'salience' DECIMAL_LITERAL ) 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 783be414b4..2a09cafd78 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 @@ -17,6 +17,7 @@ import org.drools.drl.ast.descr.AttributeDescr; import org.drools.drl.ast.descr.BaseDescr; import org.drools.drl.ast.descr.BehaviorDescr; import org.drools.drl.ast.descr.CollectDescr; +import org.drools.drl.ast.descr.EntryPointDeclarationDescr; import org.drools.drl.ast.descr.EntryPointDescr; import org.drools.drl.ast.descr.EvalDescr; import org.drools.drl.ast.descr.ExistsDescr; @@ -35,7 +36,10 @@ import org.drools.drl.ast.descr.PatternDescr; import org.drools.drl.ast.descr.PatternSourceDescr; import org.drools.drl.ast.descr.QueryDescr; import org.drools.drl.ast.descr.RuleDescr; +import org.drools.drl.ast.descr.TypeDeclarationDescr; +import org.drools.drl.ast.descr.TypeFieldDescr; import org.drools.drl.ast.descr.UnitDescr; +import org.drools.drl.ast.descr.WindowDeclarationDescr; import static org.drools.parser.DRLParserHelper.getTextWithoutErrorNode; import static org.drools.parser.ParserStringUtils.getTextPreservingWhitespace; @@ -83,6 +87,12 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { functionDescr.setDialect(dialect.getValue()); } packageDescr.addFunction(functionDescr); + } else if (descr instanceof TypeDeclarationDescr) { + packageDescr.addTypeDeclaration((TypeDeclarationDescr) descr); + } else if (descr instanceof EntryPointDeclarationDescr) { + packageDescr.addEntryPointDeclaration((EntryPointDeclarationDescr) descr); + } else if (descr instanceof WindowDeclarationDescr) { + packageDescr.addWindowDeclaration((WindowDeclarationDescr) descr); } else if (descr instanceof AttributeDescr) { packageDescr.addAttribute((AttributeDescr) descr); } else if (descr instanceof RuleDescr) { @@ -152,6 +162,47 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { return functionDescr; } + @Override + public BaseDescr visitDeclaredef(DRLParser.DeclaredefContext ctx) { + return visitDescrChildren(ctx).get(0); + } + + @Override + public TypeDeclarationDescr visitTypeDeclaration(DRLParser.TypeDeclarationContext ctx) { + TypeDeclarationDescr typeDeclarationDescr = new TypeDeclarationDescr(ctx.name.getText()); + if (ctx.EXTENDS() != null) { + typeDeclarationDescr.addSuperType(ctx.superType.getText()); + } + ctx.drlAnnotation().stream() + .map(this::visitDrlAnnotation) + .forEach(typeDeclarationDescr::addAnnotation); + ctx.field().stream() + .map(this::visitField) + .forEach(typeDeclarationDescr::addField); + return typeDeclarationDescr; + } + + @Override + public EntryPointDeclarationDescr visitEntryPointDeclaration(DRLParser.EntryPointDeclarationContext ctx) { + EntryPointDeclarationDescr entryPointDeclarationDescr = new EntryPointDeclarationDescr(); + entryPointDeclarationDescr.setEntryPointId(ctx.name.getText()); + ctx.drlAnnotation().stream() + .map(this::visitDrlAnnotation) + .forEach(entryPointDeclarationDescr::addAnnotation); + return entryPointDeclarationDescr; + } + + @Override + public WindowDeclarationDescr visitWindowDeclaration(DRLParser.WindowDeclarationContext ctx) { + WindowDeclarationDescr windowDeclarationDescr = new WindowDeclarationDescr(); + windowDeclarationDescr.setName(ctx.name.getText()); + ctx.drlAnnotation().stream() + .map(this::visitDrlAnnotation) + .forEach(windowDeclarationDescr::addAnnotation); + windowDeclarationDescr.setPattern((PatternDescr) visitLhsPatternBind(ctx.lhsPatternBind())); + return windowDeclarationDescr; + } + @Override public RuleDescr visitRuledef(DRLParser.RuledefContext ctx) { RuleDescr ruleDescr = new RuleDescr(safeStripStringDelimiters(ctx.name.getText())); @@ -219,10 +270,36 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { @Override public AnnotationDescr visitDrlAnnotation(DRLParser.DrlAnnotationContext ctx) { AnnotationDescr annotationDescr = new AnnotationDescr(ctx.name.getText()); - annotationDescr.setValue(ctx.drlArguments().drlArgument(0).getText()); + if (ctx.drlElementValue() != null) { + annotationDescr.setValue(getTextPreservingWhitespace(ctx.drlElementValue())); // single value + } else if (ctx.drlElementValuePairs() != null) { + visitDrlElementValuePairs(ctx.drlElementValuePairs(), annotationDescr); // multiple values + } return annotationDescr; } + @Override + public TypeFieldDescr visitField(DRLParser.FieldContext ctx) { + TypeFieldDescr typeFieldDescr = new TypeFieldDescr(); + typeFieldDescr.setFieldName(ctx.label().IDENTIFIER().getText()); + typeFieldDescr.setPattern(new PatternDescr(ctx.type().getText())); + if (ctx.ASSIGN() != null) { + typeFieldDescr.setInitExpr(getTextPreservingWhitespace(ctx.initExpr)); + } + ctx.drlAnnotation().stream() + .map(this::visitDrlAnnotation) + .forEach(typeFieldDescr::addAnnotation); + return typeFieldDescr; + } + + private void visitDrlElementValuePairs(DRLParser.DrlElementValuePairsContext ctx, AnnotationDescr annotationDescr) { + ctx.drlElementValuePair().forEach(pairCtx -> { + String key = pairCtx.key.getText(); + String value = getTextPreservingWhitespace(pairCtx.value); + annotationDescr.setKeyValue(key, value); + }); + } + @Override public AttributeDescr visitAttribute(DRLParser.AttributeContext ctx) { AttributeDescr attributeDescr = new AttributeDescr(ctx.getChild(0).getText()); @@ -332,7 +409,7 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { @Override public BehaviorDescr visitPatternFilter(DRLParser.PatternFilterContext ctx) { BehaviorDescr behaviorDescr = new BehaviorDescr(); - behaviorDescr.setType(ctx.label().IDENTIFIER().getText()); + behaviorDescr.setType(ctx.DRL_WINDOW().getText()); behaviorDescr.setSubType(ctx.IDENTIFIER().getText()); List<DRLParser.DrlExpressionContext> drlExpressionContexts = ctx.expressionList().drlExpression(); List<String> parameters = drlExpressionContexts.stream().map(ParserStringUtils::getTextPreservingWhitespace).collect(Collectors.toList()); 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 93a98ed9eb..9e6a97673e 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 @@ -2792,7 +2792,6 @@ class MiscDRLParserTest { } - @Disabled("Priority : High | Implement type declaration") @Test public void parse_TypeDeclarationWithFields() throws Exception { final PackageDescr pkg = parseAndGetPackageDescrFromFile( @@ -2991,7 +2990,6 @@ class MiscDRLParserTest { assertThat(fieldConstraintDescr.getExpression()).isEqualToIgnoringWhitespace("operator == Operator.EQUAL"); } - @Disabled("Priority : High | Implement type declaration") @Test public void parse_TypeWithMetaData() throws Exception { @@ -3255,7 +3253,6 @@ class MiscDRLParserTest { } - @Disabled("Priority : High | Implement entry-point declaration") @Test public void parse_EntryPointDeclaration() throws Exception { final String text = "package org.drools\n" + @@ -3277,7 +3274,6 @@ class MiscDRLParserTest { assertThat(epd.getAnnotation("foo").getValue()).isEqualTo("true"); } - @Disabled("Priority : Mid | Implement sliding window declaration") @Test public void parse_WindowDeclaration() throws Exception { final String text = "package org.drools\n" + --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
