파서가 무엇을 해야할지 모를 때의 기본 동작은 다음과 같이 터미널에 메시지를 인쇄하는 것입니다.
1:23 행 '}'에 DECIMAL 누락
이것은 좋은 메시지이지만 잘못된 위치에 있습니다. 차라리 이것을 예외로 받고 싶습니다.
나는을 사용하려고 시도 BailErrorStrategy
했지만 이것은 ParseCancellationException
메시지없이 (메시지 가 없는)을 던졌습니다 InputMismatchException
.
메시지에 유용한 정보를 유지하면서 예외를 통해 오류를보고 할 수있는 방법이 있습니까?
제가 실제로 추구하는 것은 다음과 같습니다. 일반적으로 규칙에서 작업을 사용하여 개체를 만듭니다.
dataspec returns [DataExtractor extractor]
@init {
DataExtractorBuilder builder = new DataExtractorBuilder(layout);
}
@after {
$extractor = builder.create();
}
: first=expr { builder.addAll($first.values); } (COMMA next=expr { builder.addAll($next.values); })* EOF
;
expr returns [List<ValueExtractor> values]
: a=atom { $values = Arrays.asList($a.val); }
| fields=fieldrange { $values = values($fields.fields); }
| '%' { $values = null; }
| ASTERISK { $values = values(layout); }
;
그런 다음 파서를 호출 할 때 다음과 같이합니다.
public static DataExtractor create(String dataspec) {
CharStream stream = new ANTLRInputStream(dataspec);
DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DataSpecificationParser parser = new DataSpecificationParser(tokens);
return parser.dataspec().extractor;
}
내가 정말 원하는 건
- 대한
dataspec()
입력을 해석 할 수없는 경우는 호출 예외 (이상적으로는 하나의 체크) 던져 - 해당 예외에 유용한 메시지가 있고 문제가 발견 된 줄 번호 및 위치에 대한 액세스를 제공하기 위해
그런 다음 해당 예외가 사용자에게 유용한 메시지를 제공하기에 가장 적합한 곳으로 호출 스택을 버블 링하도록 할 것입니다. 이는 네트워크 연결이 끊겼거나 손상된 파일을 읽는 것과 같은 방식입니다.
나는 행동이 이제 ANTLR4에서 "고급"으로 간주되는 것을 보았습니다. 그래서 이상한 방식으로 일을 진행하고 있을지도 모르지만, 이렇게하기위한 "고급이 아닌"방법이 이런 식으로 무엇인지 살펴 보지 않았습니다. 우리의 필요에 잘 맞았습니다.