antlr/antlr4 · critical · Exception

Precedence predicates are not supported in lexers.

Error message

Precedence predicates are not supported in lexers.

What it means

LexerATNSimulator.AdaptivePredict/closure path throws when it encounters a PRECEDENCE transition while running a lexer ATN. Precedence predicates ({p>N}?) are a parser-only feature: they resolve left-recursive rule precedence, which has no meaning during tokenization. If a serialized lexer ATN contains a precedence transition, the ATN itself is malformed for lexing purposes and the simulator refuses to continue.

Source

Thrown at runtime/CSharp/src/Atn/LexerATNSimulator.cs:499

		protected LexerATNConfig GetEpsilonTarget(ICharStream input,
											   LexerATNConfig config,
											   Transition t,
											   ATNConfigSet configs,
											   bool speculative,
											   bool treatEofAsEpsilon)
		{
			LexerATNConfig c = null;
			switch (t.TransitionType)
			{
				case TransitionType.RULE:
					RuleTransition ruleTransition = (RuleTransition)t;
					PredictionContext newContext = new SingletonPredictionContext(config.context, ruleTransition.followState.stateNumber);
					c = new LexerATNConfig(config, t.target, newContext);
					break;

				case TransitionType.PRECEDENCE:
					throw new Exception("Precedence predicates are not supported in lexers.");

				case TransitionType.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. Check atn.grammarType == ATNType.Lexer before constructing LexerInterpreter/LexerATNSimulator, and use the lexer's own serialized ATN
  2. Remove precedence predicates ({p>...}?) from lexer rules; if you need precedence-dependent lexing, restructure so the parser handles it
  3. Regenerate the grammar with the ANTLR tool version matching your runtime to rule out malformed serialization

Example fix

// before
// atn actually came from MyParser (grammar MyParser; parser rules...)
var lexInterp = new LexerInterpreter("MyLexer", vocab, ruleNames, modeNames, atn, input); // throws at runtime

// after
if (atn.grammarType != ATNType.Lexer)
    throw new InvalidOperationException("Expected a lexer ATN, got " + atn.grammarType);
var lexInterp = new LexerInterpreter("MyLexer", vocab, ruleNames, modeNames, atn, input);
Defensive patterns

Strategy: validation

Validate before calling

if (atn.grammarType != ATNType.Lexer)
    throw new InvalidOperationException($"Expected lexer ATN but got {atn.grammarType}; check which serialized ATN you passed.");

Type guard

static bool IsLexerAtn(ATN atn) => atn != null && atn.grammarType == ATNType.Lexer;

Prevention

When it happens

Trigger: A lexer ATN containing a TransitionType.PRECEDENCE edge is executed by LexerATNSimulator (the closure loop hits the PRECEDENCE case and throws). Typically caused by building a LexerInterpreter or LexerATNSimulator over an ATN that was actually serialized from a parser grammar, or by a grammar/tool bug that embedded precedence predicates in lexer rules.

Common situations: Passing a parser ATN into a lexer interpreter (mixing up the two serialized ATNs); using a left-recursive-rule grammar file as both lexer and parser source; tool/runtime version skew producing malformed serialized lexer ATNs.

Related errors


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