Skip to content

Commit d8b91ff

Browse files
authored
Enhance test/grammar coverage. function, attributes, consequence (apache#12)
* Enhance test/grammar coverage. function, attributes, consequence - better getText preserving whitespaces - resolving WARNs because of overlapping keywords * - No need to declare duplicate keywords
1 parent c11db4d commit d8b91ff

File tree

15 files changed

+500
-34
lines changed

15 files changed

+500
-34
lines changed

drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLLexer.g4

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@ import JavaLexer;
1818
// KEYWORDS
1919
/////////////////
2020

21-
DRL_PACKAGE : 'package';
21+
// These keywords are already declared in JavaLexer. They should not be overriden with different names, or else Vocabulary's literalName will be null.
22+
// So no need to declare by DRLLexer
23+
// PACKAGE : 'package';
24+
// IMPORT : 'import';
25+
// STATIC : 'static';
26+
// EXTENDS : 'extends';
27+
// SUPER : 'super';
28+
29+
// DRL keywords
2230
DRL_UNIT : 'unit';
23-
DRL_IMPORT : 'import';
2431
DRL_FUNCTION : 'function';
25-
DRL_STATIC : 'static';
2632
DRL_GLOBAL : 'global';
2733
DRL_RULE : 'rule';
2834
DRL_QUERY : 'query';
29-
DRL_EXTENDS : 'extends';
30-
DRL_SUPER : 'super';
3135
DRL_WHEN : 'when';
3236
DRL_THEN : 'then';
3337
DRL_END : 'end';

drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRLParser.g4

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ drlStatementdef
2424
| ruledef
2525
;
2626

27-
packagedef : DRL_PACKAGE name=drlQualifiedName SEMI? ;
27+
packagedef : PACKAGE name=drlQualifiedName SEMI? ;
2828

2929
unitdef : DRL_UNIT name=drlQualifiedName SEMI? ;
3030

31-
importdef : DRL_IMPORT (DRL_FUNCTION|DRL_STATIC)? drlQualifiedName (DOT MUL)? SEMI? ;
31+
importdef : IMPORT (DRL_FUNCTION|STATIC)? drlQualifiedName (DOT MUL)? SEMI? ;
3232

3333
globaldef : DRL_GLOBAL type drlIdentifier SEMI? ;
3434

3535
// rule := RULE stringId (EXTENDS stringId)? annotation* attributes? lhs? rhs END
3636

37-
ruledef : DRL_RULE name=stringId (DRL_EXTENDS stringId)? drlAnnotation* attributes? DRL_WHEN lhs DRL_THEN rhs DRL_END ;
37+
ruledef : DRL_RULE name=stringId (EXTENDS stringId)? drlAnnotation* attributes? DRL_WHEN lhs DRL_THEN rhs DRL_END ;
3838

3939
lhs : lhsExpression? ;
40-
lhsExpression : lhsOr* ;
40+
lhsExpression : lhsOr+ ;
4141
lhsOr : LPAREN DRL_OR lhsAnd+ RPAREN | lhsAnd (DRL_OR lhsAnd)* ;
4242
lhsAnd : LPAREN DRL_AND lhsUnary+ RPAREN | lhsUnary (DRL_AND lhsUnary)* ;
4343

@@ -111,16 +111,11 @@ drlIdentifier
111111
;
112112

113113
drlKeywords
114-
: DRL_PACKAGE
115-
| DRL_UNIT
116-
| DRL_IMPORT
114+
: DRL_UNIT
117115
| DRL_FUNCTION
118-
| DRL_STATIC
119116
| DRL_GLOBAL
120117
| DRL_RULE
121118
| DRL_QUERY
122-
| DRL_EXTENDS
123-
| DRL_SUPER
124119
| DRL_WHEN
125120
| DRL_THEN
126121
| DRL_END
@@ -154,7 +149,7 @@ drlExpression
154149
: drlPrimary
155150
| drlExpression bop=DOT
156151
(
157-
identifier
152+
drlIdentifier
158153
| methodCall
159154
| THIS
160155
| NEW nonWildcardTypeArguments? innerCreator
@@ -163,7 +158,7 @@ drlExpression
163158
)
164159
| drlExpression LBRACK drlExpression RBRACK
165160
| methodCall
166-
| NEW creator
161+
| NEW drlCreator
167162
| LPAREN annotation* typeType (BITAND typeType)* RPAREN drlExpression
168163
| drlExpression postfix=(INC | DEC)
169164
| prefix=(ADD|SUB|INC|DEC) drlExpression
@@ -188,8 +183,8 @@ drlExpression
188183
| switchExpression // Java17
189184

190185
// Java 8 methodReference
191-
| drlExpression COLONCOLON typeArguments? identifier
192-
| typeType COLONCOLON (typeArguments? identifier | NEW)
186+
| drlExpression COLONCOLON typeArguments? drlIdentifier
187+
| typeType COLONCOLON (typeArguments? drlIdentifier | NEW)
193188
| classType COLONCOLON typeArguments? NEW
194189
;
195190

@@ -290,11 +285,38 @@ unif : IDENTIFIER UNIFY ;
290285

291286
/* extending JavaParser blockStatement */
292287
drlRhsBlockStatement
293-
: localVariableDeclaration SEMI
288+
: drlLocalVariableDeclaration SEMI
294289
| drlRhsStatement
295290
| localTypeDeclaration
296291
;
297292

293+
/* extending JavaParser localVariableDeclaration */
294+
drlLocalVariableDeclaration
295+
: variableModifier* (typeType drlVariableDeclarators | VAR drlIdentifier ASSIGN drlExpression)
296+
;
297+
298+
/* extending JavaParser variableDeclarators */
299+
drlVariableDeclarators
300+
: drlVariableDeclarator (COMMA drlVariableDeclarator)*
301+
;
302+
303+
/* extending JavaParser variableDeclarator */
304+
drlVariableDeclarator
305+
: drlVariableDeclaratorId (ASSIGN drlVariableInitializer)?
306+
;
307+
308+
/* extending JavaParser variableDeclaratorId */
309+
drlVariableDeclaratorId
310+
: drlIdentifier (LBRACK RBRACK)*
311+
;
312+
313+
/* extending JavaParser variableInitializer */
314+
drlVariableInitializer
315+
: arrayInitializer
316+
| drlExpression
317+
;
318+
319+
298320
/* extending JavaParser statement */
299321
drlRhsStatement
300322
: blockLabel=block
@@ -309,21 +331,21 @@ drlRhsStatement
309331
| SYNCHRONIZED parExpression block
310332
| RETURN drlRhsExpression? SEMI
311333
| THROW drlRhsExpression SEMI
312-
| BREAK identifier? SEMI
313-
| CONTINUE identifier? SEMI
334+
| BREAK drlIdentifier? SEMI
335+
| CONTINUE drlIdentifier? SEMI
314336
| YIELD drlRhsExpression SEMI // Java17
315337
| SEMI
316338
| statementExpression=drlRhsExpression SEMI
317339
| switchExpression SEMI? // Java17
318-
| identifierLabel=identifier COLON drlRhsStatement
340+
| identifierLabel=drlIdentifier COLON drlRhsStatement
319341
;
320342

321343
/* extending JavaParser expression */
322344
drlRhsExpression
323345
: drlPrimary
324346
| drlRhsExpression bop=DOT
325347
(
326-
identifier
348+
drlIdentifier
327349
| methodCall
328350
| THIS
329351
| NEW nonWildcardTypeArguments? innerCreator
@@ -357,7 +379,20 @@ drlRhsExpression
357379
| switchExpression // Java17
358380

359381
// Java 8 methodReference
360-
| drlRhsExpression COLONCOLON typeArguments? identifier
361-
| typeType COLONCOLON (typeArguments? identifier | NEW)
382+
| drlRhsExpression COLONCOLON typeArguments? drlIdentifier
383+
| typeType COLONCOLON (typeArguments? drlIdentifier | NEW)
362384
| classType COLONCOLON typeArguments? NEW
363-
;
385+
;
386+
387+
drlCreator
388+
: nonWildcardTypeArguments createdName classCreatorRest
389+
| createdName (drlArrayCreatorRest | classCreatorRest)
390+
;
391+
392+
drlArrayCreatorRest
393+
: LBRACK (RBRACK (LBRACK RBRACK)* drlArrayInitializer | expression RBRACK (LBRACK expression RBRACK)* (LBRACK RBRACK)*)
394+
;
395+
396+
drlArrayInitializer
397+
: LBRACE (drlVariableInitializer (COMMA drlVariableInitializer)* (COMMA)? )? RBRACE
398+
;

drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.drools.drl.ast.descr.ExistsDescr;
1717
import org.drools.drl.ast.descr.ExprConstraintDescr;
1818
import org.drools.drl.ast.descr.FromDescr;
19+
import org.drools.drl.ast.descr.FunctionDescr;
1920
import org.drools.drl.ast.descr.FunctionImportDescr;
2021
import org.drools.drl.ast.descr.GlobalDescr;
2122
import org.drools.drl.ast.descr.ImportDescr;
@@ -68,7 +69,7 @@ public Object visitGlobaldef(DRLParser.GlobaldefContext ctx) {
6869
@Override
6970
public Object visitImportdef(DRLParser.ImportdefContext ctx) {
7071
String target = ctx.drlQualifiedName().getText() + (ctx.MUL() != null ? ".*" : "");
71-
if (ctx.DRL_FUNCTION() != null || ctx.DRL_STATIC() != null) {
72+
if (ctx.DRL_FUNCTION() != null || ctx.STATIC() != null) {
7273
FunctionImportDescr functionImportDescr = new FunctionImportDescr();
7374
functionImportDescr.setTarget(target);
7475
populateStartEnd(functionImportDescr, ctx);
@@ -82,10 +83,39 @@ public Object visitImportdef(DRLParser.ImportdefContext ctx) {
8283
return super.visitImportdef(ctx);
8384
}
8485

86+
@Override
87+
public Object visitFunctiondef(DRLParser.FunctiondefContext ctx) {
88+
FunctionDescr functionDescr = new FunctionDescr();
89+
functionDescr.setNamespace(packageDescr.getNamespace());
90+
AttributeDescr dialect = packageDescr.getAttribute("dialect");
91+
if (dialect != null) {
92+
functionDescr.setDialect(dialect.getValue());
93+
}
94+
if (ctx.typeTypeOrVoid() != null) {
95+
functionDescr.setReturnType(ctx.typeTypeOrVoid().getText());
96+
} else {
97+
functionDescr.setReturnType("void");
98+
}
99+
functionDescr.setName(ctx.IDENTIFIER().getText());
100+
DRLParser.FormalParametersContext formalParametersContext = ctx.formalParameters();
101+
DRLParser.FormalParameterListContext formalParameterListContext = formalParametersContext.formalParameterList();
102+
if (formalParameterListContext != null) {
103+
List<DRLParser.FormalParameterContext> formalParameterContexts = formalParameterListContext.formalParameter();
104+
formalParameterContexts.stream().forEach(formalParameterContext -> {
105+
DRLParser.TypeTypeContext typeTypeContext = formalParameterContext.typeType();
106+
DRLParser.VariableDeclaratorIdContext variableDeclaratorIdContext = formalParameterContext.variableDeclaratorId();
107+
functionDescr.addParameter(typeTypeContext.getText(), variableDeclaratorIdContext.getText());
108+
});
109+
}
110+
functionDescr.setBody(ParserStringUtils.getTextPreservingWhitespace(ctx.block()));
111+
packageDescr.addFunction(functionDescr);
112+
return super.visitFunctiondef(ctx);
113+
}
114+
85115
@Override
86116
public Object visitRuledef(DRLParser.RuledefContext ctx) {
87117
currentRule = new RuleDescr(safeStripStringDelimiters(ctx.name.getText()));
88-
currentRule.setConsequence(ctx.rhs().getText());
118+
currentRule.setConsequence(ParserStringUtils.getTextPreservingWhitespace(ctx.rhs()));
89119
packageDescr.addRule(currentRule);
90120

91121
Object result = super.visitRuledef(ctx);

drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/ParserStringUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.drools.parser;
22

3+
import org.antlr.v4.runtime.ParserRuleContext;
4+
import org.antlr.v4.runtime.misc.Interval;
5+
36
/**
47
* will be merged in drools-util
58
*/
@@ -17,4 +20,15 @@ public static String safeStripStringDelimiters(String value) {
1720
}
1821
return value;
1922
}
23+
24+
public static String getTextPreservingWhitespace(ParserRuleContext ctx) {
25+
int startIndex = ctx.start.getStartIndex();
26+
int stopIndex = ctx.stop.getStopIndex();
27+
if (startIndex > stopIndex) {
28+
// no text
29+
return "";
30+
}
31+
Interval interval = new Interval(startIndex, stopIndex);
32+
return ctx.start.getTokenSource().getInputStream().getText(interval);
33+
}
2034
}

drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.drools.drl.ast.descr.*;
66
import org.junit.Test;
77

8+
import static org.assertj.core.api.Assertions.assertThat;
89
import static org.drools.parser.DRLParserHelper.*;
910
import static org.junit.Assert.assertEquals;
1011
import static org.junit.Assert.assertNotNull;
@@ -60,7 +61,7 @@ public void testParse() {
6061
ExprConstraintDescr expr = (ExprConstraintDescr) constraints.get(0);
6162
assertEquals("age >= 18", expr.getExpression());
6263

63-
assertEquals("inta=4;System.out.println($p.getName());", ruleDescr.getConsequence());
64+
assertThat(ruleDescr.getConsequence().toString()).isEqualToIgnoringWhitespace("int a = 4; System.out.println($p.getName());");
6465
}
6566

6667
@Test

0 commit comments

Comments
 (0)