2013-08-06 3 views
2

ANTLR4를 사용하면서 파서에서 알고리즘 규칙 유효성 검사를 구현하는 방법과 동일한 문제가 계속 발생합니다.ANTLR4 : 일반적으로 파서 규칙의 일부를 유효하게 할 수 있습니까?

예를 들어 규칙과 일치하기 전에 "월 일 년"으로 쓰여진 날짜의 "연도"부분의 유효성을 검사하는 파서가 필요합니다. 나는 다음과 같이이 술어를 사용하여 수행 할 수 있습니다 배운 : 항상 하나의 토큰 오래되는 규칙 month에 의존하기 때문에

date : 
    {isYear(_input.LT(3).getText())}? 
     month day=INTEGER year=INTEGER  { ... } 

는하지만이 솔루션은 일반적으로하지 않습니다.

나는이에 규칙을 변경하여 나는이 문제를 해결하는 방법을 발견 거라고 생각 :

date : month day=INTEGER yearInt  { ... } ; 

yearInt returns [int i] 
    : {isYear(_input.LT(1).getText())}? 
      yr=INTEGER     { $i = $yr.int; } 
    ; 

불행하게도,이 문법은 isYear("6")이 실패하더라도, 날짜로 "7월 6일 11"전달합니다. 내가 yearInt()에 대한 XXParser.java에서 ANTLR 생성 된 코드를 통해 추적 할 때, 나는

throw new FailedPredicateException(this, "isYear(_input.LT(1).getText())"); 

를 호출하지만 코드가 다음에 수행 어쨌든 yearInt()을 받아 참조하십시오.

ANTLR 버그입니까, 아니면 내 버그입니까? 규칙의 일부를 검증해야하는 문법을 작성하는 "적절한"방법이 있습니까?

답변

1

은 분별 오류 메시지를 생성합니다

date : 
    month day=INTEGER year=INTEGER {isYear($year)}?<fail="A sensible error msg"> { ... } 
; 

또는 이들의

date : 
    month day=INTEGER year=INTEGER {if (! isYear($year)) 
             notifyErrorListeners("A sensible error msg"); 
            }  
    { ... } 
; 

을보십시오. notifyErrorListeners()는 오류를 설정하지만 진행중인 구문 분석과 관련하여 구문 분석을 "성공"시킬 수 있습니다. {isYear ($ year)}? 실패하고 더 많은 것을 찾는다.

나는이 코드를 실제로 시도하지 않았다고 고백한다. 아마도 $ year.text가 필요하고 fail 옵션과 notifyErrorListeners()가 C# 버전과 Java 버전에서 유효한지 확실하지 않습니다.

조지

관련 문제