Что означает "фрагмент" в ANTLR?

Что означает фрагмент в ANTLR?

Я видел оба правила:

fragment DIGIT : '0'..'9';

и

DIGIT : '0'..'9';

В чем разница?

Ответ 1

Фрагмент несколько похож на встроенную функцию: он делает грамматику более понятной и удобной в обслуживании.

Фрагмент никогда не будет считаться как токен, он служит только для упрощения грамматики.

Рассмотрим:

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".

См. пункт 3

Ответ 2

В соответствии с справочной книгой 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 не могут использоваться явно.