2015-03-22 2 views
0

У меня проблема, когда мне нужно проверить набор входов на бизнес-правило.ANTLR Грамматика для рекурсивного выражения

Множество входов может быть представлено классом как

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) должны return 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.

ответ

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 и проверить его (этот подход лучше, но дольше для реализации).

+0

Спасибо большое, это то, что я искал, так как я был новичком в этом, не смог построить его с нуля. Теперь я думаю, что смогу построить и развить это, чтобы удовлетворить мои требования. Принимая это как ответ – Ysak

+0

Я забыл упомянуть: выражение «*» и «*» находится перед выражением * или «*» по уважительной причине: это повлияет на приоритет (* и * обычно имеет больше приоритета, чем * или * в программировании языки в любом случае) –

+0

Я смог получить синтаксис правила. Но как я могу проверить набор входных данных против правила. Допустим, мне нужно проверить правильность RuleInput («NB», «HDFC», «VISA») против правила payType в («NB») и (банк в («HDFC», «AXIS») или бренд в («VISA»)) и должен возвращать true. Не могли бы вы рассказать мне что-то в этом. – Ysak

Смежные вопросы