Что означает фрагмент в ANTLR?
Я видел оба правила:
fragment DIGIT : '0'..'9';
и
DIGIT : '0'..'9';
В чем разница?
Что означает фрагмент в ANTLR?
Я видел оба правила:
fragment DIGIT : '0'..'9';
и
DIGIT : '0'..'9';
В чем разница?
Фрагмент несколько похож на встроенную функцию: он делает грамматику более понятной и удобной в обслуживании.
Фрагмент никогда не будет считаться как токен, он служит только для упрощения грамматики.
Рассмотрим:
NUMBER: DIGITS | OCTAL_DIGITS | HEX_DIGITS;
fragment DIGITS: '1'..'9' '0'..'9'*;
fragment OCTAL_DIGITS: '0' '0'..'7'+;
fragment HEX_DIGITS: '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+;
В этом примере соответствие NUMBER будет всегда возвращать NUMBER в лексер, независимо от того, соответствует ли оно "1234", "0xab12" или "0777".
В соответствии с справочной книгой Definitive Antlr4:
Правила с префиксом фрагмента можно вызывать только из других правил лексера; они не являются самими токенами.
на самом деле они улучшат читаемость ваших грамматик.
посмотрите на этот пример:
STRING : '"' (ESC | ~["\\])* '"' ;
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ;
fragment UNICODE : 'u' HEX HEX HEX HEX ;
fragment HEX : [0-9a-fA-F] ;
STRING - это лексер с использованием правила фрагмента, такого как ESC. Unnicode используется в правиле Esc, а Hex используется в правиле фрагмента Unicode. Правила ESC и UNICODE и HEX не могут использоваться явно.
В этом сообщении в блоге есть очень четкий пример, где fragment
имеет существенное значение:
grammar number;
number: INT;
DIGIT : '0'..'9';
INT : DIGIT+;
Грамматика распознает "42", но не "7". Вы можете исправить это, сделав цифру фрагментом (или перемещая DIGIT после INT).