antlr/antlr4 · error · FailedPredicateException
precpred(_ctx, %d)
Error message
precpred(_ctx, %d)
What it means
ParserInterpreter throws FailedPredicateException("precpred(_ctx, N)") when it walks a precedence-predicate transition and the runtime predicate test precpred(ctx, N) returns false — i.e. the parse context's precedence is too low for the alternative being entered (left-recursive rule semantics). The formatted message names the precedence level that failed. In a normal generated parser the adaptivePredict machinery avoids entering such alternatives, so this fires when the interpreter follows an ATN path the prediction would have rejected.
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/ParserInterpreter.java:289
}
break;
case Transition.PREDICATE:
PredicateTransition predicateTransition = (PredicateTransition)transition;
if (!sempred(_ctx, predicateTransition.ruleIndex, predicateTransition.predIndex)) {
throw new FailedPredicateException(this);
}
break;
case Transition.ACTION:
ActionTransition actionTransition = (ActionTransition)transition;
action(_ctx, actionTransition.ruleIndex, actionTransition.actionIndex);
break;
case Transition.PRECEDENCE:
if (!precpred(_ctx, ((PrecedencePredicateTransition)transition).precedence)) {
throw new FailedPredicateException(this, String.format("precpred(_ctx, %d)", ((PrecedencePredicateTransition)transition).precedence));
}
break;
default:
throw new UnsupportedOperationException("Unrecognized ATN transition type.");
}
setState(transition.target.stateNumber);
}
/** Method visitDecisionState() is called when the interpreter reaches
* a decision state (instance of DecisionState). It gives an opportunity
* for subclasses to track interesting things.
*/
protected int visitDecisionState(DecisionState p) {
int predictedAlt = 1;
if ( p.getNumberOfTransitions()>1 ) {
getErrorHandler().sync(this);View on GitHub (pinned to 7d5770395b)
Solutions
- Ensure the serialized ATN and the runtime come from the same ANTLR version (regenerate/re-serialize)
- Catch FailedPredicateException and inspect e.getCtx()/e.getPredicate() to identify which precedence level failed
- Prefer generated parsers over ParserInterpreter when possible — prediction in generated code prunes these alternatives correctly
- Validate the grammar's precedence structure (checkLeftRecursion output from the tool) before interpreting it
Example fix
// before
parserInterpreter.expression(); // throws FailedPredicateException mid-parse
// after
try { parserInterpreter.expression(); }
catch (FailedPredicateException e) {
errors.add("precedence predicate failed: " + e.getMessage()
+ " at " + e.getOffendingToken().getText());
} Defensive patterns
Strategy: try-catch
Try / catch
try {
parserInterpreter.startRule();
} catch (FailedPredicateException e) {
// message is 'precpred(_ctx, N)'; ctx and offending token identify the spot
errors.add(e.getMessage() + " at line " + e.getOffendingToken().getLine());
} Prevention
- Keep serialized ATNs and the runtime on the same ANTLR version
- Prefer generated parsers for grammars with left-recursive precedence rules
- Validate grammar tool output (warnings about left recursion) before interpreting
When it happens
Trigger: Running a grammar with left-recursive expression rules through ParserInterpreter (grammar loaded at runtime, not generated code); corrupted or version-mismatched serialized ATN where precedence transitions no longer match rule contexts; manually driving visitState/transition logic.
Common situations: Generic grammar-runner tools and IDE plugins that interpret grammars; deserializing an ATN produced by a different ANTLR version than the runtime interpreting it; precedence-climbing expression grammars (expr: expr '*' expr | expr '+' expr | INT with precedence options).
Related errors
- precpred(_ctx, {})
- Unrecognized ATN transition type.
- Couldn't identify final state of the precedence rule prefix
- Precedence predicates are not supported in lexers.
- Unrecognized ATN transition type.
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/480a4843f4ef1918.
Report an issue: GitHub.