2012-11-14 5 views
3

비교적 간단한 IF/THEN 언어를 평가하고 있지만 문제가 발생했습니다 : 정수와 날짜를 모두 YYYYMMDD 형식으로 일치시켜야합니다. 진짜 정규 표현식을 쓸 수 있다면 이것을 쉽게 풀 수 있지만 ANTLR 솔루션을 찾지 못했습니다.ANTLR 날짜와 정수 매칭

문법은 다음과 같다 : 구문 분석 할 필요 성명의

//overall rule to evaluate a single expression 
singleEvaluation returns [boolean evalResult] 
    : integerEvaluation {$evalResult = $integerEvaluation.evalResult;} 
    | dateEvaluation {$evalResult = $dateEvaluation.evalResult;} 
    // etc 
    ; 


dateEvaluation returns [boolean evalResult] 
    : expr1=(INTEGER|'TODAY'|DATE_FIELD_IDENTIFIER) (leftOp=('+'|'-') leftModifier=INTEGER leftQualifier=DATE_QUALIFIER)? 
    operator=(EQ|NE|LT|LE|GT|GE) 
    expr2=(INTEGER|'TODAY'|DATE_FIELD_IDENTIFIER) (rightOp=('+'|'-') rightModifier=INTEGER rightQualifier=DATE_QUALIFIER)? 
{ // code } 

integerEvaluation returns [boolean evalResult] 
    : expr1=(NUM_FIELD_IDENTIFIER|INTEGER) 
    operator=(EQ|NE|LT|LE|GT|GE) 
    expr2=(NUM_FIELD_IDENTIFIER|INTEGER) 
    { // code 
    } 
    ; 

fragment DIGIT: '0'..'9'; 
INTEGER: DIGIT+; 
DATE_FIELD_IDENTIFIER: ('DOB'|'DATE_OF_HIRE'); 
NUM_FIELD_IDENTIFIER: ('AGE'|'DEPARTMENT_ID'); 
DATE_QUALIFIER:('YEAR'|'YEARS'|'MONTH'|'MONTHS'|'DAY'|'DAYS'|'TODAY'); 
EQ:'='; 
NE: '<>'; 
LT: '<'; 
LE: '<='; 
GT: '>'; 
GE: '>='; 

예는 "65> AGE"또는 "AGE < 65"과 같은, 또는 "DOB> 19500101 '이 될 것입니다.

파서가 INTEGER와 8 자리 날짜 형식을 구분할 수있는 방법을 제안 해 줄 수 있습니까? 렉서는 INTEGER 일치 한

답변

3

, 당신은 ($text를 통해 참조)의 일치하는 텍스트를 검사 할 수 있습니다, 그리고 사용자 정의 검사를 기반으로, INTEGER에서 DATE에이 유형의 변경을 결정한다. DATE 규칙은 빈 fragment 규칙으로 만들 수 있으며 일반 구문 분석기 규칙처럼 파서 규칙 내에서 사용할 수 있습니다.

빠른 데모 :

INTEGER 
: DIGIT+ 
    { 
    // If this token starts with either '19' or '20', followed 
    // by 6 digits, change it to a DATE-token. 
    if ($text.matches("(19|20)\\d{6}")) { 
     $type = DATE; 
    } 
    } 
; 

fragment DATE : /* empty! */ ; 

그리고 파서 규칙에, 당신은 단지 DATE을 사용할 수 있습니다 : 두 번 하루에

dateEvaluation 
: DATE ... 
; 
+0

이잖아. 도움을 다시 한번 주셔서 감사합니다. – Jason

+0

문제 없습니다 @ 제이슨 ... 다시 :) –