Как отобразить удобную ошибку разбора ANTLR - PullRequest
0 голосов
/ 25 октября 2019

Я хотел бы отобразить удобную для пользователя вставку ошибки в ANTLR4.

Вот пример допустимого текста для моего синтаксического анализатора:

aaaa AND bbb AND @FD $sysdate

Когда я удаляю доллар $, у меня естьхорошая ошибка синтаксического анализа

aaaa AND bbb AND @FD sysdate
line 1:21 mismatched input 'sysdate' expecting {' ', '$'}

Когда я делаю опечатку в sysdate, у меня появляется хорошая ошибка синтаксического анализа

aaaa AND bbb AND @FD $sysABCdate
line 1:22 token recognition error at: 'sysABCdate'
line 1:32 missing {'sysdate', 'SYSDATE'} at '<EOF>'

Когда я пропускаю AND перед @ FD

aaaa AND bbb YYY @FD $sysdate

У меня есть фактическое сообщение об ошибке

line 1:0 token recognition error at: 'aaaa AND bbb YYY @FD $sysdate'
line 1:29 mismatched input '<EOF>' expecting BODY_WITH_FIELD_CODE

, в то время как я ожидал бы что-то более удобное для пользователя, например

token error at YYY, missing {'AND'}

Вот мое определение ANTLR

//rules
mainQ : base EOF ;
base : BODY_WITH_FIELD_CODE filling_date_condition;
filling_date_condition : ' '* sys_date_minus_number;
sys_date_minus_number : sys_date_with_dollar_prefix;
sys_date_with_dollar_prefix : '$'('sysdate'|'SYSDATE');

//TOKENS
BODY_WITH_FIELD_CODE : .+? ('and'|'AND') WS+ FD_WITH_AT;
FD_WITH_AT : '@' FD;
fragment WS : ' ';
fragment FD : 'fd'|'FD';

1 Ответ

0 голосов
/ 25 октября 2019

Проблема в том, что синтаксический анализатор говорит правду - он только обнаружил, что не может сопоставить входные данные в самом конце.

Три основных способа несоответствия входных данных:

  • Правило требует, чтобы был определенный токен, но другой токен был на входе
    • Затем выдается ошибка, когда токен ожидался
  • Правило имеет две или более альтернативы (т. Е. Пути, по которым может следовать синтаксический анализатор), и вход не соответствует ни одной из этих
    • Тогда ошибка (NoViableAlternative) выдается в точке ввода, гдевход не соответствует какой-либо альтернативе
  • Правило требует больше токенов, но мы уже в конце ввода
    • Тогда ошибка выдается в концеinput

* * * * .+? является виновником здесь. Это не жадно соответствует чему-либо. То, что произошло здесь:

  • Математически aaaa AND bbb, как и ожидалось
    • Вот где он остановился во всех предыдущих случаях, так как увидел AND @FD
  • Но в этот последний раз AND @FD не было, поэтому не жадность не вступила в силу, и правило продолжало потреблять ввод, пока оно не потребляло aaaa AND bbb YYY @FD $sysdate
  • И вот, наконецпонял, что нет никакого способа сопоставить входные данные, поскольку он ожидает AND, но видит EOF
...