我遇到问题,我需要针对业务规则验证一组输入。
输入集可以用类似
的类表示public class RuleInput{
public String payType;
public String bank;
public String brand;
//....Getters and setters
}
我的系统客户端可以在我的系统中配置许多规则。要配置规则,我已经定义了如下所示的DSL
RULE1 - payType in ('NB,'CC') and bank in ('HDFC', 'CITI')
RULE2 - payType in ('NB') and (bank in ('HDFC','AXIS') or brand in ('VISA'))
现在给定ruleInput = RuleInput(NB,HDFC,VISA)和函数
public boolean validateAgainstRule(String ruleId, RuleInput input);
调用这个像validateAgainstRule(“RULE2”,ruleInput)应该返回true;
我正在考虑使用ANTLR(但我对它很新)。我试着像这样构建一个语法
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 ;
有人可以帮我写出我的要求的语法。我想我甚至需要在语法中使用动作来接受输入。
注意:我甚至想过使用drools,但我只有一种 对于这种规模来说,使用drools会很重要 问题。所以想过只使用ANTLR。
答案 0 :(得分:1)
我的语法中有一些我不理解的东西 - 它似乎与你的DSL不相符......
在这里,请尝试这样做:
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将为您生成一个基本树访问者类,使用它来检查您的表达式,或者构建一个AST并检查它(这种方法更好但实现时间更长)。