I have problem where I need to validate a set of inputs against a business rule.
The set of inputs can be represented by a class like
public class RuleInput{
public String payType;
public String bank;
public String brand;
//....Getters and setters
}
My system client can configure many rules in my system. To configure rule i have defined a DSL like below
RULE1 - payType in ('NB,'CC') and bank in ('HDFC', 'CITI')
RULE2 - payType in ('NB') and (bank in ('HDFC','AXIS') or brand in ('VISA'))
Now Given ruleInput = RuleInput(NB,HDFC, VISA) and function
public boolean validateAgainstRule(String ruleId, RuleInput input);
Calling this like validateAgainstRule("RULE2" , ruleInput) should return true;
I am thinking of using ANTLR for the same(But I am very new to it). I tried to build a grammar like this
expression :
primary_expression
| expression OR expression
| expression AND expression
| LPAREN expression RPAREN
;
primary_expression : //A simple expression
simple
;
simple : TAG_EXPR | BIN_EXPR ;
TAG : 'payment_type' | 'issuer' | 'brand' ;
BIN_TAG : 'bins' ;
BIN_EXPR : BIN_TAG IN BIN_LIST ;
TAG_EXPR : TAG IN LIST ;
LIST : LPAREN TEXT (COMMA TEXT)* RPAREN ;
BIN_LIST : LPAREN BIN (COMMA BIN)* RPAREN ;
IN : 'in' ;
OR : 'or' ;
AND : 'and' ;
LPAREN : '(' ;
RPAREN : ')' ;
COMMA : ',' ;
TEXT : [A-Z]+ ;
BIN : [0-9][0-9][0-9][0-9][0-9][0-9] ;
WS : [ \t\r\n]+ -> skip ;
Can somebody help me to write the grammar for my requirement. I think I need even to use actions in the grammar for accepting inputs.
Note : I even thought of using drools, but I only have a single kind of rules, it will be heavy to use drools for this kind of a small problem. So thought of going with ANTLR only.
There are a couple things I don't understand in your grammar - it doesn't seem to match your DSL...
Here, try this instead:
rule : ID '-' expression ;
expression : '(' expression ')' # parensExpr
| expression 'and' expression # andExpr
| expression 'or' expression # orExpr
| simpleExpr # clauseExpr
;
simpleExpr : TAG 'in' '(' stringList ')' ;
stringList : STRING (',' STRING)* ;
TAG : 'payType' | 'bank' | 'brand';
STRING : '\'' [A-Za-z0-9]* '\\';
ID: [A-Za-z0-9]+;
WS: [ \t\r\n]+ -> skip ;
ANTLR will generate a base tree visitor class for you, use this to check your expression, or build an AST and check against that (this approach is better but longer to implement).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.