그래서 ANTLR을 사용하여 Java로 컴파일러를 작성하고 있으며 오류를 처리하는 방법에 다소 의문이 생깁니다.ANTLR이 구문 오류를 억제하지 못하게하는 방법은 무엇입니까?
기본 동작은 오류 메시지를 인쇄 한 다음 토큰 삽입 등을 통해 오류를 복구하고 구문 분석을 계속하는 것 같습니다. 나는 원칙적으로 이것을 좋아한다. 즉, 사용자가 둘 이상의 구문 오류를 범하면 (가장 좋은 경우) 오류 당 하나의 메시지가 표시되지만 모든 오류를 다시 컴파일하여 다음 오류를 발견하도록 강요하지는 않습니다. 기본 오류 메시지는 내 용도에 적합합니다. 문제는 모든 토큰을 읽었을 때 발생합니다.
물론 ANTLR의 트리 생성자를 사용하여 추상 구문 트리를 작성합니다. 구문 분석을 계속 진행하여 사용자가 모든 오류를 볼 수 있도록 구문 분석을 계속하는 것은 좋지만 구문 분석이 끝나면 입력이 구문 적으로 유효하지 않다는 표시 또는 예외를 얻고 싶습니다. 그런 식으로 컴파일을 중단하고 사용자에게 "죄송합니다. 구문 오류를 수정 한 다음 다시 시도하십시오"라고 말할 수 있습니다. 내가 원하지 않는 것은 사용자가 말하고자하는 바를 토대로 불완전한 AST를 내뱉고 아무 것도 잘못되었다는 표시없이 컴파일의 다음 단계로 진행하는 것이다. 콘솔과 나는 볼 수 없다). 그러나 기본적으로 정확하게 작동합니다. RecognitionException
들 던져 mismatch
및 recoverFromMismatchedSet
방법을 무시하고, 동일한 작업을 수행 할 수있는 @rulecatch
액션을 추가 :
는 확실한 ANTLR 참조 즉시 구문 오류가 감지되는 구문 분석을 중지하는 기술을 제공합니다. 이것은 구문 분석 오류를 복구하는 이점을 잃어 버리는 것처럼 보일 수 있지만 더 중요한 것은 부분적으로 만 작동한다는 것입니다. 필요한 토큰이 누락 된 경우 (예 : 2 진 연산자가 한쪽에만 표현식이있는 경우) 예상대로 예외가 발생하지만 불필요한 토큰이 추가되면 ANTLR은 거기에 속한다고 생각되는 토큰을 삽입합니다 콘솔 메시지를 제외하고 구문 오류가 표시되지 않은 상태로 AST를 생성합니다. 설상가상으로, 삽입 된 토큰은 EOF
이므로 파일의 나머지 부분도 파싱되지 않았습니다.
isValid
필드에 다음을 추가하여 문제를 해결할 수 있습니다. 구문 분석이 끝날 때 오류가 발생하면 예외를 throw하도록 구문 분석기 및 재정의 메서드와 동작을 추가합니다. 그러나 더 좋은 방법이 있습니까? 나는 ANTLR 사용자들 사이에서 내가하려고하는 것이 이상하다는 것을 상상할 수 없다.
유용합니다 (ANTLR 3.4를 사용하고 있습니다). 그러나 실제로 RecognitionException을 던질 곳은 어디입니까? 가능한 경우 복구하는 것이 좋지만 AST를 생성하는 대신 구문 분석 끝에 예외를 던지십시오. – Taymon
@Taymon 구문 분석 후 'getNumberOfSyntaxErrors'를 검사하고 파서를 호출 한 코드가 수행 할 작업을 결정하도록하는 것이 좋습니다. 불일치 토큰을 복구하려는 경우 파서 자체에서 던져 볼 때 장점이 없습니다. 파서가 깨끗한 실행을 시도하도록하고 호출자가 충분히 깨끗한 지 결정하도록하십시오. – user1201210
렉서와 파서 모두에서'getNumberOfSyntaxErrors'를 검사하고, 어느 것이 든 0이 아니면 예외를 던집니다. – Apalala