antlr/antlr4 · error · UnsupportedOperationException

Precedence predicates are not supported in lexers.

Error message

Precedence predicates are not supported in lexers.

What it means

LexerATNSimulator.getEpsilonTarget() walks lexer ATN transitions and explicitly rejects transitions of type PRECEDENCE: '{' ... '}' precedence predicates are a parser (left-recursion) feature and have no defined semantics during lexing, so encountering one raises UnsupportedOperationException. It means the lexer ATN itself contains a precedence predicate transition, which stock grammars never produce.

Source

Thrown at runtime/Python3/src/antlr4/atn/LexerATNSimulator.py:372

                configs.add(config)

        for t in config.state.transitions:
            c = self.getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon)
            if c is not None:
                currentAltReachedAcceptState = self.closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon)

        return currentAltReachedAcceptState

    # side-effect: can alter configs.hasSemanticContext
    def getEpsilonTarget(self, input:InputStream, config:LexerATNConfig, t:Transition, configs:ATNConfigSet,
                                           speculative:bool, treatEofAsEpsilon:bool):
        c = None
        if t.serializationType==Transition.RULE:
                newContext = SingletonPredictionContext.create(config.context, t.followState.stateNumber)
                c = LexerATNConfig(state=t.target, config=config, context=newContext)

        elif t.serializationType==Transition.PRECEDENCE:
                raise UnsupportedOperationException("Precedence predicates are not supported in lexers.")

        elif t.serializationType==Transition.PREDICATE:
                #  Track traversing semantic predicates. If we traverse,
                # we cannot add a DFA state for this "reach" computation
                # because the DFA would not test the predicate again in the
                # future. Rather than creating collections of semantic predicates
                # like v3 and testing them on prediction, v4 will test them on the
                # fly all the time using the ATN not the DFA. This is slower but
                # semantically it's not used that often. One of the key elements to
                # this predicate mechanism is not adding DFA states that see
                # predicates immediately afterwards in the ATN. For example,

                # a : ID {p1}? | ID {p2}? ;

                # should create the start state for rule 'a' (to save start state
                # competition), but should not create target of ID state. The
                # collection of ATN states the following ID references includes
                # states reached by traversing predicates. Since this is when we

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Remove precedence predicates / left-recursion style constructs from lexer rules — use semantic predicates ({self.input.LA(1)...}) in the lexer instead.
  2. Regenerate artifacts with matching tool/runtime versions to rule out a misdeserialized ATN.
  3. Ensure you are not running LexerATNSimulator against a parser's serialized ATN.

Example fix

// before (lexer rule using precedence-style construct -> unsupported)
// expr: {prec}? ...  // parser-only feature

// after (lexer-level lookahead via semantic predicate)
FRAG: {self._input.LA(1) == ord('$')}? '$' ;
Defensive patterns

Strategy: validation

Validate before calling

# keep precedence constructs out of lexer rules; use semantic predicates for lexer context
# grep your grammar: lexer rules must not contain '{n,prec}?' style precedence predicates
import re
bad = re.findall(r'^[A-Z_]+\s*:[^;]*\{\d+[>,]', grammar_text, re.M)
assert not bad, 'precedence predicate in lexer rule(s): %s' % bad

Try / catch

from antlr4.error.Errors import LexerNoViableAltException  # unrelated; this error is UnsupportedOperationException
try:
    lexer.nextToken()
except UnsupportedOperationException as e:
    if 'Precedence predicates' in str(e):
        raise RuntimeError('grammar bug: precedence predicate used in a lexer rule')
    raise

Prevention

When it happens

Trigger: A lexer ATN containing precedence-predicate transitions — only reachable with malformed/hand-crafted serialized ATN data or a serious tool/runtime format mismatch; user code introspecting the lexer ATN and crossing such a transition.

Common situations: Attempting to use left-recursive precedence constructs in lexer rules; experimenting with hand-built ATNs; version-skew artifacts where a parser ATN is fed to the lexer simulator.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/7bc4a2001db3d23b. Report an issue: GitHub.