Skip to content

Commit

Permalink
[DROOLS-7288] Failed to parse complex parentheses (#27)
Browse files Browse the repository at this point in the history
* [DROOLS-7288] Failed to parse complex parentheses
- bump to 8.43.0.Final

* additional tests
  • Loading branch information
tkobayas authored and rgdoliveira committed Oct 24, 2024
1 parent 977ce82 commit c346cfc
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@ globaldef : DRL_GLOBAL type drlIdentifier SEMI? ;

ruledef : DRL_RULE name=stringId (EXTENDS stringId)? drlAnnotation* attributes? lhs rhs DRL_END ;

lhs : DRL_WHEN lhsExpression? ;
lhsExpression : lhsOr+ ;
lhsOr : LPAREN DRL_OR lhsAnd+ RPAREN | lhsAnd (DRL_OR lhsAnd)* ;
lhsAnd : LPAREN lhsAnd RPAREN | LPAREN DRL_AND lhsUnary+ RPAREN | lhsUnary (DRL_AND lhsUnary)* ;
lhs : DRL_WHEN lhsExpression* ;

lhsExpression : LPAREN lhsExpression RPAREN #lhsExpressionEnclosed
| lhsUnary #lhsUnarySingle
| LPAREN DRL_AND lhsExpression+ RPAREN #lhsAnd
| lhsExpression (DRL_AND lhsExpression)+ #lhsAnd
| LPAREN DRL_OR lhsExpression+ RPAREN #lhsOr
| lhsExpression (DRL_OR lhsExpression)+ #lhsOr
;

/*
lhsUnary : ( lhsExists namedConsequence?
Expand All @@ -57,6 +62,7 @@ lhsUnary : (
| lhsNot
| lhsPatternBind
) ;

lhsPatternBind : label? ( LPAREN lhsPattern (DRL_OR lhsPattern)* RPAREN | lhsPattern ) ;

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,12 @@ public AttributeDescr visitAttribute(DRLParser.AttributeContext ctx) {
@Override
public List<BaseDescr> visitLhs(DRLParser.LhsContext ctx) {
if (ctx.lhsExpression() != null) {
return visitLhsExpression(ctx.lhsExpression());
return visitDescrChildren(ctx);
} else {
return new ArrayList<>();
}
}

@Override
public List<BaseDescr> visitLhsExpression(DRLParser.LhsExpressionContext ctx) {
return visitDescrChildren(ctx);
}

@Override
public BaseDescr visitLhsPatternBind(DRLParser.LhsPatternBindContext ctx) {
if (ctx.lhsPattern().size() == 1) {
Expand Down Expand Up @@ -294,33 +289,25 @@ public NotDescr visitLhsNot(DRLParser.LhsNotContext ctx) {
return notDescr;
}

@Override
public BaseDescr visitLhsExpressionEnclosed(DRLParser.LhsExpressionEnclosedContext ctx) {
return (BaseDescr) visit(ctx.lhsExpression());
}

@Override
public BaseDescr visitLhsOr(DRLParser.LhsOrContext ctx) {
if (!ctx.DRL_OR().isEmpty()) {
OrDescr orDescr = new OrDescr();
List<BaseDescr> descrList = visitDescrChildren(ctx);
descrList.forEach(orDescr::addDescr);
return orDescr;
} else {
// No DRL_OR means only one lhsAnd
return visitLhsAnd(ctx.lhsAnd().get(0));
}
OrDescr orDescr = new OrDescr();
List<BaseDescr> descrList = visitDescrChildren(ctx);
descrList.forEach(orDescr::addDescr);
return orDescr;
}

@Override
public BaseDescr visitLhsAnd(DRLParser.LhsAndContext ctx) {
if (ctx.lhsAnd() != null) {
return visitLhsAnd(ctx.lhsAnd());
}
if (!ctx.DRL_AND().isEmpty()) {
AndDescr andDescr = new AndDescr();
List<BaseDescr> descrList = visitDescrChildren(ctx);
descrList.forEach(andDescr::addDescr);
return andDescr;
} else {
// No DRL_AND means only one lhsUnary
return visitLhsUnary(ctx.lhsUnary().get(0));
}
AndDescr andDescr = new AndDescr();
List<BaseDescr> descrList = visitDescrChildren(ctx);
descrList.forEach(andDescr::addDescr);
return andDescr;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1389,22 +1389,21 @@ public void parse_OrBindingWithBrackets() throws Exception {
assertThat((String) rule.getConsequence()).isEqualToIgnoringWhitespace( "System.out.println( \"Mark and Michael\" + bar );");
}

@Disabled("Priority : High | Failed to parse complex parentheses")
@Test
public void parse_BracketsPrecedence() throws Exception {
void parenthesesOrAndOr() throws Exception {
final PackageDescr pkg = parseAndGetPackageDescrFromFile(
"brackets_precedence.drl" );

assertThat(pkg.getRules().size()).isEqualTo(1);
assertThat(pkg.getRules()).hasSize(1);
final RuleDescr rule = (RuleDescr) pkg.getRules().get( 0 );

final AndDescr rootAnd = (AndDescr) rule.getLhs();

assertThat(rootAnd.getDescrs().size()).isEqualTo(2);
assertThat(rootAnd.getDescrs()).hasSize(2);

final OrDescr leftOr = (OrDescr) rootAnd.getDescrs().get( 0 );

assertThat(leftOr.getDescrs().size()).isEqualTo(2);
assertThat(leftOr.getDescrs()).hasSize(2);
final NotDescr not = (NotDescr) leftOr.getDescrs().get( 0 );
final PatternDescr foo1 = (PatternDescr) not.getDescrs().get( 0 );
assertThat(foo1.getObjectType()).isEqualTo("Foo");
Expand All @@ -1413,13 +1412,114 @@ public void parse_BracketsPrecedence() throws Exception {

final OrDescr rightOr = (OrDescr) rootAnd.getDescrs().get( 1 );

assertThat(rightOr.getDescrs().size()).isEqualTo(2);
assertThat(rightOr.getDescrs()).hasSize(2);
final PatternDescr shoes = (PatternDescr) rightOr.getDescrs().get( 0 );
assertThat(shoes.getObjectType()).isEqualTo("Shoes");
final PatternDescr butt = (PatternDescr) rightOr.getDescrs().get( 1 );
assertThat(butt.getObjectType()).isEqualTo("Butt");
}

@Test
void parenthesesAndOrOr() {
final String drl = "rule and_or_or\n" +
" when\n" +
" (Foo(x == 1) and Bar(x == 2)) or (Foo(x == 3) or Bar(x == 4))\n" +
" then\n" +
"end";
PackageDescr pkg = parser.parse(drl);

assertThat(pkg.getRules()).hasSize(1);
final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
final AndDescr rootAnd = (AndDescr) rule.getLhs();
assertThat(rootAnd.getDescrs()).hasSize(1);

final OrDescr topOr = (OrDescr) rootAnd.getDescrs().get(0);
assertThat(topOr.getDescrs()).hasSize(2);

final AndDescr leftAnd = (AndDescr) topOr.getDescrs().get(0);
assertThat(leftAnd.getDescrs()).hasSize(2);
final PatternDescr foo1 = (PatternDescr) leftAnd.getDescrs().get(0);
assertThat(foo1.getObjectType()).isEqualTo("Foo");
final PatternDescr bar1 = (PatternDescr) leftAnd.getDescrs().get(1);
assertThat(bar1.getObjectType()).isEqualTo("Bar");

final OrDescr rightOr = (OrDescr) topOr.getDescrs().get(1);
assertThat(rightOr.getDescrs()).hasSize(2);
final PatternDescr foo2 = (PatternDescr) rightOr.getDescrs().get(0);
assertThat(foo2.getObjectType()).isEqualTo("Foo");
final PatternDescr bar2 = (PatternDescr) rightOr.getDescrs().get(1);
assertThat(bar2.getObjectType()).isEqualTo("Bar");
}

@Test
void parenthesesOrAndAnd() {
final String drl = "rule or_and_and\n" +
" when\n" +
" (Foo(x == 1) or Bar(x == 2)) and (Foo(x == 3) and Bar(x == 4))\n" +
" then\n" +
"end";
PackageDescr pkg = parser.parse(drl);

assertThat(pkg.getRules()).hasSize(1);
final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
final AndDescr rootAnd = (AndDescr) rule.getLhs();
assertThat(rootAnd.getDescrs()).hasSize(2);

final OrDescr leftOr = (OrDescr) rootAnd.getDescrs().get(0);
assertThat(leftOr.getDescrs()).hasSize(2);
final PatternDescr foo1 = (PatternDescr) leftOr.getDescrs().get(0);
assertThat(foo1.getObjectType()).isEqualTo("Foo");
final PatternDescr bar1 = (PatternDescr) leftOr.getDescrs().get(1);
assertThat(bar1.getObjectType()).isEqualTo("Bar");

final AndDescr rightAnd = (AndDescr) rootAnd.getDescrs().get(1);
assertThat(rightAnd.getDescrs()).hasSize(2);
final PatternDescr foo2 = (PatternDescr) rightAnd.getDescrs().get(0);
assertThat(foo2.getObjectType()).isEqualTo("Foo");
final PatternDescr bar2 = (PatternDescr) rightAnd.getDescrs().get(1);
assertThat(bar2.getObjectType()).isEqualTo("Bar");
}

@Test
void parenthesesAndOrOrOrAnd() throws Exception {
final String drl = "rule and_or_or_or_and\n" +
" when\n" +
" (Foo(x == 1) and (Bar(x == 2) or Foo(x == 3))) or (Bar(x == 4) or (Foo(x == 5) and Bar(x == 6)))\n" +
" then\n" +
"end";
PackageDescr pkg = parser.parse(drl);

assertThat(pkg.getRules()).hasSize(1);
final RuleDescr rule = (RuleDescr) pkg.getRules().get(0);
final AndDescr rootAnd = (AndDescr) rule.getLhs();
assertThat(rootAnd.getDescrs()).hasSize(1);

final OrDescr topOr = (OrDescr) rootAnd.getDescrs().get(0);
assertThat(topOr.getDescrs()).hasSize(2);

final AndDescr leftAnd = (AndDescr) topOr.getDescrs().get(0);
assertThat(leftAnd.getDescrs()).hasSize(2);
final PatternDescr foo1 = (PatternDescr) leftAnd.getDescrs().get(0);
assertThat(foo1.getObjectType()).isEqualTo("Foo");
final OrDescr leftOr = (OrDescr) leftAnd.getDescrs().get(1);
assertThat(leftOr.getDescrs()).hasSize(2);
final PatternDescr bar1 = (PatternDescr) leftOr.getDescrs().get(0);
assertThat(bar1.getObjectType()).isEqualTo("Bar");
final PatternDescr foo2 = (PatternDescr) leftOr.getDescrs().get(1);
assertThat(foo2.getObjectType()).isEqualTo("Foo");

final OrDescr rightOr = (OrDescr) topOr.getDescrs().get(1);
assertThat(rightOr.getDescrs()).hasSize(2);
final PatternDescr bar2 = (PatternDescr) rightOr.getDescrs().get(0);
assertThat(bar2.getObjectType()).isEqualTo("Bar");
final AndDescr rightAnd = (AndDescr) rightOr.getDescrs().get(1);
assertThat(rightAnd.getDescrs()).hasSize(2);
final PatternDescr foo3 = (PatternDescr) rightAnd.getDescrs().get(0);
assertThat(foo3.getObjectType()).isEqualTo("Foo");
final PatternDescr bar3 = (PatternDescr) rightAnd.getDescrs().get(1);
assertThat(bar3.getObjectType()).isEqualTo("Bar");
}

@Disabled("Priority : High | Implement eval")
@Test
public void parse_EvalMultiple() throws Exception {
Expand Down

0 comments on commit c346cfc

Please sign in to comment.