A lexer action is a block of arbitrary code in the target language surrounded by {...}, which is executed during matching:
IDENTIFIER: [A-Z]+ { log("matched rule"); };
A semantic predicate is a block of arbitrary code in the target language surrounded by {...}?, which evaluates to a boolean value. If the returned value is false, the lexer rule is skipped.
IDENTIFIER: [A-Z]+ { identifierIsValid() }?;
Semantic predicates should be defined at the end of the rule whenever possible for performance reasons.