The usual answer to dealing with context-dependant elements is to move
the decision from the lexer into the parser.
You might do this:
identifier: (ID_FRAGMENT '!' ID_FRAGMENT) => ID_FRAGMENT '!' ID_FRAGMENT
| ID_FRAGMENT
/* You still have to deal with the other suffixes */
;
ID_FRAGMENT: LETTER (LETTER| DECIMAL_LITERAL)* ;
...Richard