Skip to content

Commit

Permalink
[DROOLS-7306] Implement unification (apache#41)
Browse files Browse the repository at this point in the history
* [DROOLS-7306] Implement unification
- Also [DROOLS-7307] Parse attribute agenda-group

* [DROOLS-7308] Parse attribute without value
- Also [DROOLS-7309] Parse attribute with parentheses
  • Loading branch information
tkobayas committed Oct 20, 2023
1 parent 701641e commit c784d99
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ DRL_BIG_INTEGER_LITERAL
/////////////////

HASH : '#';
UNIFY : ':=' ;
DRL_UNIFY : ':=' ;
NULL_SAFE_DOT : '!.' ;
QUESTION_DIV : '?/' ;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ lhsUnary : (
| lhsPatternBind
) SEMI? ;

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

/*
lhsPattern : xpathPrimary (OVER patternFilter)? |
Expand Down Expand Up @@ -253,6 +253,7 @@ drlExpression
| drlExpression bop=INSTANCEOF (typeType | pattern)
| drlExpression bop=DRL_MATCHES drlExpression
| drlExpression DRL_NOT? DRL_MEMBEROF drlExpression
| drlExpression bop=DRL_UNIFY drlExpression
| drlExpression bop=(EQUAL | NOTEQUAL) drlExpression
| drlExpression bop=BITAND drlExpression
| drlExpression bop=CARET drlExpression
Expand Down Expand Up @@ -438,12 +439,15 @@ drlElementValue
;

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' ) DRL_STRING_LITERAL
| 'calendars' DRL_STRING_LITERAL ( COMMA DRL_STRING_LITERAL )*
| 'timer' ( DECIMAL_LITERAL | TEXT )
| 'duration' ( DECIMAL_LITERAL | TEXT ) ;
attribute : name=( 'salience' | 'enabled' ) conditionalOrExpression #expressionAttribute
| name=( 'no-loop' | 'auto-focus' | 'lock-on-active' | 'refract' | 'direct' ) BOOL_LITERAL? #booleanAttribute
| name=( 'agenda-group' | 'activation-group' | 'ruleflow-group' | 'date-effective' | 'date-expires' | 'dialect' ) DRL_STRING_LITERAL #stringAttribute
| name='calendars' DRL_STRING_LITERAL ( COMMA DRL_STRING_LITERAL )* #stringListAttribute
| name='timer' ( DECIMAL_LITERAL | chunk ) #intOrChunkAttribute
| name='duration' ( DECIMAL_LITERAL | TIME_INTERVAL | LPAREN TIME_INTERVAL RPAREN ) #durationAttribute
;

chunk : LPAREN .+? RPAREN;

assignmentOperator : ASSIGN
| ADD_ASSIGN
Expand All @@ -457,7 +461,7 @@ assignmentOperator : ASSIGN
| LT LT ASSIGN ;

label : IDENTIFIER COLON ;
unif : IDENTIFIER UNIFY ;
unif : IDENTIFIER DRL_UNIFY ;

/* extending JavaParser variableInitializer */
drlVariableInitializer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.drools.drl.ast.descr.TypeFieldDescr;
import org.drools.drl.ast.descr.UnitDescr;
import org.drools.drl.ast.descr.WindowDeclarationDescr;
import org.drools.util.StringUtils;

import static org.drools.parser.DRLParserHelper.getTextWithoutErrorNode;
import static org.drools.parser.ParserStringUtils.getTextPreservingWhitespace;
Expand Down Expand Up @@ -95,10 +96,9 @@ private void applyChildrenDescrs(PackageDescr packageDescr, List<BaseDescr> desc
packageDescr.addWindowDeclaration((WindowDeclarationDescr) descr);
} else if (descr instanceof AttributeDescr) {
packageDescr.addAttribute((AttributeDescr) descr);
} else if (descr instanceof RuleDescr) {
} else if (descr instanceof RuleDescr) { // QueryDescr extends RuleDescr
packageDescr.addRule((RuleDescr) descr);
} else if (descr instanceof QueryDescr) {
packageDescr.addRule((QueryDescr) descr);
packageDescr.afterRuleAdded((RuleDescr) descr);
}
});
}
Expand Down Expand Up @@ -301,12 +301,75 @@ private void visitDrlElementValuePairs(DRLParser.DrlElementValuePairsContext ctx
}

@Override
public AttributeDescr visitAttribute(DRLParser.AttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.getChild(0).getText());
if (ctx.getChildCount() > 1) {
// TODO : will likely split visitAttribute methods using labels (e.g. #stringAttribute)
String value = unescapeJava(safeStripStringDelimiters(ctx.getChild(1).getText()));
attributeDescr.setValue(value);
public AttributeDescr visitExpressionAttribute(DRLParser.ExpressionAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
attributeDescr.setValue(getTextPreservingWhitespace(ctx.conditionalOrExpression()));
attributeDescr.setType(AttributeDescr.Type.EXPRESSION);
return attributeDescr;
}

@Override
public AttributeDescr visitBooleanAttribute(DRLParser.BooleanAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
attributeDescr.setValue(ctx.BOOL_LITERAL() != null ? ctx.BOOL_LITERAL().getText() : "true");
attributeDescr.setType(AttributeDescr.Type.BOOLEAN);
return attributeDescr;
}

@Override
public AttributeDescr visitStringAttribute(DRLParser.StringAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
attributeDescr.setValue(unescapeJava(safeStripStringDelimiters(ctx.DRL_STRING_LITERAL().getText())));
attributeDescr.setType(AttributeDescr.Type.STRING);
return attributeDescr;
}

@Override
public AttributeDescr visitStringListAttribute(DRLParser.StringListAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
List<String> valueList = ctx.DRL_STRING_LITERAL().stream()
.map(ParseTree::getText)
.collect(Collectors.toList());
attributeDescr.setValue(createStringList(valueList));
attributeDescr.setType(AttributeDescr.Type.LIST);
return attributeDescr;
}

private static String createStringList(List<String> valueList) {
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (int i = 0; i < valueList.size(); i++) {
sb.append(valueList.get(i));
if (i < valueList.size() - 1) {
sb.append(", ");
}
}
sb.append(" ]");
return sb.toString();
}

@Override
public AttributeDescr visitIntOrChunkAttribute(DRLParser.IntOrChunkAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
if (ctx.DECIMAL_LITERAL() != null) {
attributeDescr.setValue(ctx.DECIMAL_LITERAL().getText());
attributeDescr.setType(AttributeDescr.Type.NUMBER);
} else {
attributeDescr.setValue(getTextPreservingWhitespace(ctx.chunk()));
attributeDescr.setType(AttributeDescr.Type.EXPRESSION);
}
return attributeDescr;
}

@Override
public AttributeDescr visitDurationAttribute(DRLParser.DurationAttributeContext ctx) {
AttributeDescr attributeDescr = new AttributeDescr(ctx.name.getText());
if (ctx.DECIMAL_LITERAL() != null) {
attributeDescr.setValue(ctx.DECIMAL_LITERAL().getText());
attributeDescr.setType(AttributeDescr.Type.NUMBER);
} else {
attributeDescr.setValue(unescapeJava(safeStripStringDelimiters(ctx.TIME_INTERVAL().getText())));
attributeDescr.setType(AttributeDescr.Type.EXPRESSION);
}
return attributeDescr;
}
Expand Down Expand Up @@ -338,6 +401,9 @@ private PatternDescr getSinglePatternDescr(DRLParser.LhsPatternBindContext ctx)
.orElseThrow(() -> new IllegalStateException("lhsPatternBind must have at least one lhsPattern : " + ctx.getText()));
if (ctx.label() != null) {
patternDescr.setIdentifier(ctx.label().IDENTIFIER().getText());
} else if (ctx.unif() != null) {
patternDescr.setIdentifier(ctx.unif().IDENTIFIER().getText());
patternDescr.setUnification(true);
}
return patternDescr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1651,7 +1651,6 @@ public void parse_Comment() throws Exception {
assertThat(pkg.getName()).isEqualTo("foo.bar");
}

@Disabled("Priority : High | Parse attribute without value => true")
@Test
public void parse_Attributes() throws Exception {
final RuleDescr rule = parseAndGetFirstRuleDescrFromFile(
Expand Down Expand Up @@ -1731,7 +1730,6 @@ public void parse_Attributes2() throws Exception {

}

@Disabled("Priority : High | Parse attribute without value => true")
@Test
public void parse_AttributeRefract() throws Exception {
final String source = "rule Test refract when Person() then end";
Expand All @@ -1751,7 +1749,6 @@ public void parse_AttributeRefract() throws Exception {

}

@Disabled("Priority : High | Parse attribute with parentheses")
@Test
public void parse_EnabledExpression() throws Exception {
final RuleDescr rule = parseAndGetFirstRuleDescrFromFile(
Expand All @@ -1775,7 +1772,6 @@ public void parse_EnabledExpression() throws Exception {
assertThat(at.getValue()).isEqualTo("true");
}

@Disabled("Priority : High | Parse attribute with parentheses")
@Test
public void parse_DurationExpression() throws Exception {
final RuleDescr rule = parseAndGetFirstRuleDescrFromFile(
Expand All @@ -1795,7 +1791,6 @@ public void parse_DurationExpression() throws Exception {
assertThat(at.getValue()).isEqualTo("true");
}

@Disabled("Priority : Mid | Parse calendar attribute")
@Test
public void parse_Calendars() throws Exception {
final RuleDescr rule = parseAndGetFirstRuleDescrFromFile(
Expand All @@ -1815,7 +1810,6 @@ public void parse_Calendars() throws Exception {
assertThat(at.getValue()).isEqualTo("true");
}

@Disabled("Priority : Mid | Parse calendar attribute")
@Test
public void parse_Calendars2() throws Exception {
final RuleDescr rule = parseAndGetFirstRuleDescrFromFile(
Expand Down Expand Up @@ -1905,7 +1899,6 @@ public void parse_SoundsLike() throws Exception {
pat.getConstraint();
}

@Disabled("Priority : High | Parse attribute agenda-group")
@Test
public void parse_PackageAttributes() throws Exception {
final PackageDescr pkg = parseAndGetPackageDescrFromFile(
Expand Down Expand Up @@ -3132,7 +3125,6 @@ public void parse_PositionalsAndNamedConstraints() throws Exception {

}

@Disabled("Priority : High | Implement unification")
@Test
public void parse_UnificationBinding() throws Exception {
final String text = "rule X when $p := Person( $name := name, $loc : location ) then end";
Expand Down

0 comments on commit c784d99

Please sign in to comment.