У меня проблема с обработкой ошибок в Antlr 4, когда я вызываю метод notifyErrorListeners("msg")
в моем настраиваемом прослушивателе, Antlr не дает мне точную строку и позицию ошибки. Вот часть моего DSL.
study( region = "region" , timestamp = 12:10 , processType = "processType")
...
Моя проблема в том, что грамматика допускает дублирование переменных в исследовании, например.
study( region = "region" , region = "region" , timestamp = 12:10)
...
Так что в качестве решения я решаю управляйте этим в моем пользовательском слушателе. Вот мой слушатель
@Getter
public class StudyPatternListener extends StudyBaseListener {
private Map<String, Object> studyParams = new HashMap<>();
@Setter
private StudyParser parser;
@Override
public void enterStudyAssignProcessType(StudyAssignProcessTypeContext ctx) {
String processType = ctx.STRING().getText().replace("\"", "");
if (!this.studyParams.containsKey("processType")) {
this.studyParams.put("processType", processType);
} else {
// here Antlr doesn't give me the right line and the right position of the error.
parser.notifyErrorListeners("processType parameter is already assigned");
}
}
Вот мой пользовательский слушатель ошибок.
public class StudyErrorListener extends BaseErrorListener {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
System.err.println("line = " + line + ", position = " + charPositionInLine + " , msg = " + msg);
}
}
Вот моя грамматика.
grammar Study;
program: main EOF; // the program rule.
// LINE_COMMENT*
main: NEWLINE* study NEWLINE* ; // the main rule;
study : 'study' '(' studyParameters ')';
studyParameters: (| ( studyAssign (',' studyAssign)*) ); // assign in the study
studyAssign: 'timestamp' '=' TIMESTAMP # studyAssignTimestamp
| 'region' '=' STRING # studyAssignRegion
| 'processType' '=' STRING # studyAssignProcessType
| 'businessDate' '=' DATE # studyAssignBusinessDate
; // valid study parameters .
fragment LETTER : [A-Za-z];
fragment DIGIT : [0-9];
fragment TWODIGIT : DIGIT DIGIT;
TIMESTAMP: TWODIGIT ':' TWODIGIT;
DATE : TWODIGIT TWODIGIT ;
ID : LETTER+;
STRING : '"' ( ~ '"' )* '"' ;
NEWLINE:'\r'? '\n' ;
LINE_COMMENT: '#' ~[\r\n]* -> skip;
WS : [ \t]+ -> skip ;