Как устранить неоднозначность текста с помощью ANTLR4, который иногда состоит из двух токенов, а иногда и третьего?
У меня проблема с грамматикой ANTLR4. Мне нужно проанализировать текст, который содержит 6 символов AN. Исходя из контекста текста, он может представлять: - идентификатор 6-AN (номер бронирования рейса - PNR - который выглядит как 7B22MS или JPN92Y или аналогичный), - указатель авиакомпании (две буквы) + номер рейса (четыре цифры), например, LH1856.
Проблема в том, что если я создаю правила лексера, которые разбирают авиакомпанию, номер и идентификатор PNR, как это:
Авиакомпания: 'A'.. 'Z''A'.. 'Z';
FlNum: ('0'.. '9') ('0'.. '9') ('0'.. '9') ('0'.. '9');
PNR: ('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('А'..'Z'|'0'..'9')('А'..'Z'|'0'..'9')('A "..'Z'|'0'..'9');
тогда правило PNR всегда выигрывает и съедает все токены, которые соответствуют его шаблону.
Как я могу изменить это так, чтобы Airline и FlNum были проанализированы, если контекст грамматики нуждается в них?
2 ответа
Как насчет этого:
AirlineAndFlNm : 'A'..'Z' 'A'..'Z' ('0'..'9')('0'..'9')('0'..'9')('0'..'9');
PNR : ('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9')('A'..'Z'|'0'..'9');
или более читаемый:
AirlineAndFlNm : LETTER LETTER DIGIT DIGIT DIGIT DIGIT ;
PNR : AlphaNum AlphaNum AlphaNum AlphaNum AlphaNum AlphaNum;
// fragments can only be used by other rules, will never create a token on their own
fragment LETTER: 'A'..'Z';
fragment DIGIT : '0'..'9';
fragment AlphaNum: LETTER | DIGIT ;
Должно быть легко отделить AirlineAndFlNm
после этого. И с тех пор AirlineAndFlNm
помещен перед PNR
, это будет соответствовать, если это возможно.
Позвольте лексеру маркировать отдельные символы и продвигать эти правила в правилах синтаксического анализа:
// parser rules
airline
: LETTER
;
fl_num
: DIGIT DIGIT DIGIT DIGIT
;
pnr
: alpha_num alpha_num alpha_num alpha_num alpha_num alpha_num
;
alpha_num
: DIGIT
| LETTER
;
// lexer rules
DIGIT
: [0-9]
;
LETTER
: [A-Z]
;