I am trying to write a simple grammar in ANTLR4 and use it for my project, but I cannot wrap my head around this problem. Let's say I got the grammar:
parser grammar GrammarParser;
ranks : RANKS COLON entry* ;
entry : rank who SEMICOLON ;
rank : RANK_HIGH | RANK_LOW ;
who : ID ;
lexer grammar GrammarLexer;
RANKS : 'ranks' ;
RANK_HIGH : 'high' ;
RANK_LOW : 'low' ;
ID : [a-zA-Z]+ ;
COLON : ':' ;
SEMICOLON : ';' ;
WS : [ \t\r\n]+ -> skip ;
The problem is that with those grammars this simple example collapses the whole idea:
ranks: low ranks; high high; ranks ranks;
First of all the lexer will return the following stream of tokens for it:
RANKS COLON ID RANKS SEMICOLON ID ID SEMICOLON RANKS RANKS SEMICOLON
which shows the problem. RANKS should be a keyword only for that starting spot - instead it goes over the places where I define (at least in rules) RANKS and ID should be (the first and third entries). Similarly, as RANKS is defined before anything else, lexer chooses over before RANK_HIGH/RANK_LOW/ID (when it and any of those match the same sign sequence from streams). Similarly for ID over RANK_HIGH/RANK_LOW.
So all-in-all I can use 'ranks' everywhere, but it will always be used as RANKS and I cannot use 'high'/'low', because they will always be recognized as ID. Also, ID cannot be 'ranks', because of the priority reasons as well.
Modes do not seem all that helpful here, because the grammar does not indicate when ranks really ends, so it cannot pop modes after reaching it (considering it might be just a small part of the whole file to parse).
Is there any solution for that?