2012-07-04 1 views
2

런타임에 입력 한 "VERB1 OR (VERB2 AND VERB3) OR (VERB4)"와 같은 논리적 표현식을 평가하려면 어떻게해야합니까? 동사 *는 특정 조건을 평가하기위한 자리 표시 자입니다. 예를 들어, VERB1은 데이터베이스에 레코드가 존재하는지 확인하는 것을 의미 할 수 있습니다. VERB1에 해당하는 경우런타임시 논리 표현식을 평가하십시오.

표현에서 "VERB1 OR (VERB2 및 VERB3) OR (VERB4)", 다른 동사가 실행되어서는 안

편집 : http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/에 설명 예 내가 뭘하려고 오전과 매우 유사 보인다 . 그러나 최적화 단계 (VERB1이 참이면 다른 동사를 실행해서는 안 됨)가없는 것 같습니다.

+0

당신을 가지고 Drools, http://openrules.com/ 등의 규칙 엔진을 사용해 보셨습니까? 또 다른 대안은 Ognl 또는 MVEL 또는 Spring EL (http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html)을 활용하는 것입니다. –

+0

Drools를 간략하게 살펴 보았지만 다른 것은 아닙니다. 우리는 Drools가 우리 프로젝트에 소개 할 과잉 인 것 같았고 이것이이 문제를 해결할 지 명확하지 않았습니다. – dsatish

답변

1

, 당신은 너무처럼 그루비의 실종 재산 방법과 the GroovyShell base class setting를 사용할 수 있습니다

import org.codehaus.groovy.control.CompilerConfiguration 

// The command to be executes 
def command = "VERB1 || (VERB2 && VERB3) || (VERB4)" 

// Set a base class for the GroovyShell 
new CompilerConfiguration().with { compiler -> 
    compiler.scriptBaseClass = 'VerbHandlingBaseClass' 
    new GroovyShell(this.class.classLoader, new Binding(), compiler).with { shell -> 
    // and evaluate the command 
    shell.evaluate(command) 
    } 
} 

abstract class VerbHandlingBaseClass extends Script { 
    boolean VERB1() { 
    System.out.println('CHECK THE DATABASE, RETURN FALSE') 
    false 
    } 

    boolean VERB2() { 
    System.out.println('WRITE A LOG ENTRY RETURN TRUE') 
    true 
    } 

    boolean VERB3() { 
    System.out.println('VALIDATE SOMETHING, RETURN TRUE') 
    true 
    } 

    boolean VERB4() { 
    System.out.println('THIS WONT BE REACHED, AS VERB2 && VERB3 == true') 
    true 
    } 

    def propertyMissing(String name) { 
    "$name"() 
    } 
} 

인쇄해야 그 :

CHECK THE DATABASE, RETURN FALSE 
WRITE A LOG ENTRY RETURN TRUE 
VALIDATE SOMETHING, RETURN TRUE 
+0

이것이 제게 효과적이라고 생각합니다. 감사! – dsatish

0

태그에 ANTLR을 언급했습니다.이 기능을 사용 했습니까? ANTLR에서 완전한 부울 문법을 만들 수는 있지만 동사를 평가하는 방법의 수준까지 내려 가면 훨씬 더 어려워진다.

쿼리 할 수있는 작고 고정 된 동사 세트가있는 경우 동사와 함수 간의 매핑을 쉽게 만들 수 있습니다.

동사의 목록이 더 큰 경우 리플렉션을 사용하여 특정 방법을 호출하여이를 평가할 수 있습니다.

동사가 수학적 비교를 포함 할 수있는 경우 수학 어휘 분석기와 구문 분석기를 만들 때이 모든 것이 조금 더 어려워집니다.

ANTLR에서 시도한 것에 대해 더 구체적인 질문이나 지식이 없으면 나는 더 많은 조언을 드릴 수 있을지 확신하지 못합니다.

편집 : 귀하의 의견을 토대로 좀 더 추가하겠습니다. 당신은 당신의 문법 구문 분석 규칙을 추가 할 수 있습니다

boolean_or returns [boolean b] 
    : b1=boolean_and {$b = $b1.b;} 
     (OR b2=boolean_and {$b = $b || $b2.b;})* 
    ; 

boolean_atom returns [boolean b] 
    : 
    ((numeric_comparison)=> b1=numeric_comparison {$b = $b1.b;} 
    | TRUE {$b = true;} | FALSE {$b = false;} 
    | s1=VERB {$b = evalVerb($s1.s);} 
    | LPAREN b1=boolean_expr RPAREN {$b = $b1.b;} 
    ) 

; 

을 내가 현재 사용하고 부울 파서의 작은 부분 이잖아. 공란을 채울 수 있습니다.

그리고 조기 반환 귀하의 요구 사항을 고려하지 않는

ANTLRStringStream in = new ANTLRStringStream(booleanString); 
ActionLexer lexer = new ActionLexer(in); 
CommonTokenStream tokens = new CommonTokenStream(lexer); 
BooleanParser parser = new BooleanParser(tokens); 
try { 
    return parser.eval(); 
} catch (Exception e) { 
} 

이 같은 것을 사용하여 파서를 호출,하지만 난 당신이 그렇게하는 방법을 알아낼 수 있습니다 확신합니다.

이것은 일을하는 가장 좋은 방법은 아니지만 과거에 나를 위해 일하는 방법이었습니다. 희망이 도움이됩니다. 당신이 ANDOR 대신에 ||&&를 사용할 수있는 경우

+0

방금 ​​ANTLR을 탐색하기 시작했습니다. 내 이해에서, 문법을 정의함으로써, ANTLR은 나무를 생성 할 것이다. (http : // stackoverflow에있는 표현 트리와 비슷하다.com/questions/4589951/파싱 - 산술 표현식 - 및 - 건물에서 - 나무 - 그것 - 자바에서). 평가자는 ANTLR에 의해 제공되지 않습니다. – dsatish

+0

내가 말하는 "평가자"는 ANLTR 용어로 "Tree Parser"로 알려져 있습니다. – dsatish