Когда вы ставите ключевое слово fragment
перед правилом лексера, вы не можете использовать это правило в правилах синтаксического анализатора.fragment
может использоваться только внутри других правил лексера.Такие правила никогда не становятся токенами сами по себе, их можно использовать только как часть других токенов (других правил лексера).
Другими словами: удалите эти ключевые слова fragment
из своей грамматики:
// parser rules
compilationUnit : relativePath;
relativePath : identifier (SLASH identifier)*;
identifier : IdentifierStart (IdentifierStart | Digit)*;
// lexer rules
SLASH : '/';
IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';
Digit : '0'..'9';
Однако, относительный путь также может быть превращен в один токен, и в этом случае вы можете оставить ключевые слова fragment
, но должны превратить некоторые правила синтаксического анализатора в правила лексера, например:
// parser rule
compilationUnit : RelativePath;
// lexer rules
RelativePath : Identifier ('/' Identifier)*;
fragment Identifier : IdentifierStart IdentifierPart*;
fragment IdentifierPart : 'a'..'z' | 'A'..'Z' | '_' | '0'..'9';
fragment IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';
Но тогда для анализатора никогда не будет создан токен Identifier
, поскольку RelativePath соответствует одному Identifier
.Для этого Identifier
также должен быть fragment
.Так что, возможно, это не то, что вы хотите.