Reputation: 21
I'm trying to use more than one lexer command on a lexer rule. My code looks something like that:
LEXER_RULE: something->mode(NUMBER);
mode NUMBER;
NU: [0-9]+ ->mode(ANOTHER_MODE); //Going into another mode in case the NU rule is used
//now leaving the NUMBER mode, in case there is no number written
NO_NUM: ~[0-9]->mode(DEFAULT_MODE);
The lexer rule NU is only optional, so I have to cover the case that it is not used. However, I would also like to skip everything that is inside NO_NUM. Something like
NO_NUM:~[0-9]->skip ->mode(DEFAULT_MODE);
I know that I am not allowed to use more than one lexer command on one lexer rule. Does anyone know any other approach? I need to be able to leave the mode somehow. Btw I am not allowed to use semantic predicates. Thanks!
Upvotes: 1
Views: 223
Reputation: 170308
You were almost there! Use a comma insetad:
NO_NUM : ~[0-9] -> skip, mode(DEFAULT_MODE);
This, obviously, discards anything that ~[0-9]
matches. So, if you have this grammar:
ID : [a-zA-Z]+;
...
mode NUMBER;
NU. : [0-9]+ -> mode(ANOTHER_MODE);
NO_NUM : ~[0-9] -> skip, mode(DEFAULT_MODE);
mode ANOTHER_MODE;
...
And in mode NUMBER
you encounter abc
, then a
is discarded, and bc
will be made into an ID
. If you also want the a
to be part of the ID
, then you need to do this:
ID : [a-zA-Z]+;
...
mode NUMBER;
NU. : [0-9]+ -> mode(ANOTHER_MODE);
NO_NUM : ~[0-9] -> more, mode(DEFAULT_MODE);
mode ANOTHER_MODE;
...
More about Lexer Command: https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#lexer-commands
Upvotes: 1