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 c5de3bade535cce18be955990f420cf5bf466191 Author: Toshiya Kobayashi <[email protected]> AuthorDate: Thu May 18 20:52:48 2023 +0900 [DROOLS-7286] Failed to parse binding with || (#21) --- .../src/main/antlr4/org/drools/parser/DRLParser.g4 | 4 +-- .../java/org/drools/parser/DRLParserHelper.java | 12 +++---- .../java/org/drools/parser/DRLParserWrapper.java | 2 +- .../java/org/drools/parser/DRLVisitorImpl.java | 42 +++++++--------------- .../java/org/drools/parser/ParserStringUtils.java | 7 ++++ .../java/org/drools/parser/MiscDRLParserTest.java | 2 -- 6 files changed, 28 insertions(+), 41 deletions(-) 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 e1b625306c..be4ab9c671 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 @@ -67,14 +67,14 @@ lhsPattern : xpathPrimary (OVER patternFilter)? | lhsPattern : QUESTION? objectType=drlQualifiedName LPAREN positionalConstraints? constraints? RPAREN (DRL_FROM patternSource)? ; positionalConstraints : constraint (COMMA constraint)* SEMI ; constraints : constraint (COMMA constraint)* ; -constraint : label? ( nestedConstraint | conditionalOrExpression ) ; +constraint : ( nestedConstraint | conditionalOrExpression ) ; nestedConstraint : ( IDENTIFIER ( DOT | HASH ) )* IDENTIFIER DOT LPAREN constraints RPAREN ; conditionalOrExpression : left=conditionalAndExpression (OR right=conditionalAndExpression)* ; conditionalAndExpression : left=inclusiveOrExpression (AND right=inclusiveOrExpression)* ; inclusiveOrExpression : left=exclusiveOrExpression (BITOR right=exclusiveOrExpression)* ; exclusiveOrExpression : left=andExpression (CARET right=andExpression)* ; andExpression : left=equalityExpression (BITAND right=equalityExpression)* ; -equalityExpression : left=instanceOfExpression ( ( op=EQUAL | op=NOTEQUAL ) right=instanceOfExpression )* ; +equalityExpression : label? 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 : left=drlExpression (right=orRestriction)* ; diff --git a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java index 9d42bf0964..3bd15b3f4f 100644 --- a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java +++ b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java @@ -4,6 +4,7 @@ import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; @@ -15,11 +16,8 @@ public class DRLParserHelper { } public static PackageDescr parse(String drl) { - return compilationUnitContext2PackageDescr(createParseTree(drl)); - } - - public static DRLParser.CompilationUnitContext createParseTree(String drl) { - return createDrlParser(drl).compilationUnit(); + DRLParser drlParser = createDrlParser(drl); + return compilationUnitContext2PackageDescr(drlParser.compilationUnit(), drlParser.getTokenStream()); } public static DRLParser createDrlParser(String drl) { @@ -29,8 +27,8 @@ public class DRLParserHelper { return new DRLParser(commonTokenStream); } - public static PackageDescr compilationUnitContext2PackageDescr(DRLParser.CompilationUnitContext ctx) { - DRLVisitorImpl visitor = new DRLVisitorImpl(); + public static PackageDescr compilationUnitContext2PackageDescr(DRLParser.CompilationUnitContext ctx, TokenStream tokenStream) { + DRLVisitorImpl visitor = new DRLVisitorImpl(tokenStream); Object descr = visitor.visit(ctx); if (descr instanceof PackageDescr) { return (PackageDescr) descr; diff --git a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java index 7bfdcd8904..06992f0440 100644 --- a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java +++ b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserWrapper.java @@ -26,7 +26,7 @@ public class DRLParserWrapper { errors.addAll(errorListener.getErrors()); try { - return compilationUnitContext2PackageDescr(cxt); + return compilationUnitContext2PackageDescr(cxt, drlParser.getTokenStream()); } catch (Exception e) { LOGGER.error("Exception while creating PackageDescr", e); errors.add(new DRLParserError(e)); 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 fcc05872af..2a2a2088ef 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,14 +2,13 @@ package org.drools.parser; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; 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.antlr.v4.runtime.tree.TerminalNode; import org.drools.drl.ast.descr.AndDescr; import org.drools.drl.ast.descr.AnnotationDescr; import org.drools.drl.ast.descr.AttributeDescr; @@ -30,11 +29,19 @@ import org.drools.drl.ast.descr.RuleDescr; import org.drools.drl.ast.descr.UnitDescr; import static org.drools.parser.DRLParserHelper.getTextWithoutErrorNode; +import static org.drools.parser.ParserStringUtils.getTextPreservingWhitespace; +import static org.drools.parser.ParserStringUtils.getTokenTextPreservingWhitespace; import static org.drools.parser.ParserStringUtils.safeStripStringDelimiters; import static org.drools.util.StringUtils.unescapeJava; public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { + private TokenStream tokenStream; + + public DRLVisitorImpl(TokenStream tokenStream) { + this.tokenStream = tokenStream; + } + @Override public PackageDescr visitCompilationUnit(DRLParser.CompilationUnitContext ctx) { PackageDescr packageDescr = new PackageDescr(); @@ -119,7 +126,7 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { functionDescr.addParameter(typeTypeContext.getText(), variableDeclaratorIdContext.getText()); }); } - functionDescr.setBody(ParserStringUtils.getTextPreservingWhitespace(ctx.block())); + functionDescr.setBody(getTextPreservingWhitespace(ctx.block())); return functionDescr; } @@ -145,7 +152,7 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { if (ctx.rhs() != null) { ruleDescr.setConsequenceLocation(ctx.rhs().getStart().getLine(), ctx.rhs().getStart().getCharPositionInLine()); // location of "then" - ruleDescr.setConsequence(ParserStringUtils.getTextPreservingWhitespace(ctx.rhs().consequence())); + ruleDescr.setConsequence(getTextPreservingWhitespace(ctx.rhs().consequence())); } return ruleDescr; @@ -342,31 +349,8 @@ public class DRLVisitorImpl extends DRLParserBaseVisitor<Object> { } // leaves of constraint concatenate return Strings - private String visitConstraintChildren(RuleNode node) { - return ((ParserRuleContext) node).children.stream() - .map(c -> c instanceof TerminalNode ? c : c.accept(this)) - .filter(Objects::nonNull) - .map(Object::toString) - .collect(Collectors.joining(" ")); - } - - @Override - public Object visitChildren(RuleNode node) { - if (hasConstraintAsAncestor(node)) { - return visitConstraintChildren(node); - } - return super.visitChildren(node); - } - - private boolean hasConstraintAsAncestor(RuleNode node) { - ParseTree parent = node.getParent(); - if (parent instanceof DRLParser.ConstraintContext) { - return true; - } else if (parent == null) { - return false; - } else { - return hasConstraintAsAncestor((RuleNode) parent); - } + private String visitConstraintChildren(ParserRuleContext ctx) { + return getTokenTextPreservingWhitespace(ctx, tokenStream); } private Optional<BaseDescr> visitFirstDescrChild(RuleNode node) { diff --git a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/ParserStringUtils.java b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/ParserStringUtils.java index 58410e9ea3..0fcef4e5a1 100644 --- a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/ParserStringUtils.java +++ b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/ParserStringUtils.java @@ -1,6 +1,7 @@ package org.drools.parser; import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.misc.Interval; /** @@ -22,6 +23,7 @@ public class ParserStringUtils { } public static String getTextPreservingWhitespace(ParserRuleContext ctx) { + // Using raw CharStream int startIndex = ctx.start.getStartIndex(); int stopIndex = ctx.stop.getStopIndex(); if (startIndex > stopIndex) { @@ -31,4 +33,9 @@ public class ParserStringUtils { Interval interval = new Interval(startIndex, stopIndex); return ctx.start.getTokenSource().getInputStream().getText(interval); } + + public static String getTokenTextPreservingWhitespace(ParserRuleContext ctx, TokenStream tokenStream) { + // tokenStream is required to get hidden channel token (e.g. whitespace). Unlike getTextPreservingWhitespace, this method reflects Lexer normalizeString + return tokenStream.getText(ctx.start, ctx.stop); + } } 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 9e896cd6e0..d053f6ae29 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 @@ -3114,7 +3114,6 @@ class MiscDRLParserTest { assertThat(ecd.getExpression()).isEqualTo("bigDecimal < 50B"); } - @Disabled("Priority : High | Failed to parse binding with ||") @Test public void parse_BindingComposite() throws Exception { final String text = "rule X when Person( $name : name == \"Bob\" || $loc : location == \"Montreal\" ) then end"; @@ -3130,7 +3129,6 @@ class MiscDRLParserTest { assertThat(((ExprConstraintDescr) constraints.get(0)).getExpression()).isEqualTo("$name : name == \"Bob\" || $loc : location == \"Montreal\""); } - @Disabled("Priority : High | Failed to parse binding with ||") @Test public void parse_BindingCompositeWithMethods() throws Exception { final String text = "rule X when Person( $name : name.toUpperCase() == \"Bob\" || $loc : location[0].city == \"Montreal\" ) then end"; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
