{"record":{"id":"480a4843f4ef1918","repo":"antlr/antlr4","slug":"precpred-ctx-d","errorCode":null,"errorMessage":"precpred(_ctx, %d)","messagePattern":"precpred\\(_ctx, (.+?)\\)","errorType":"exception","errorClass":"FailedPredicateException","httpStatus":null,"severity":"error","filePath":"runtime/Java/src/org/antlr/v4/runtime/ParserInterpreter.java","lineNumber":289,"sourceCode":"\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase Transition.PREDICATE:\n\t\t\t\tPredicateTransition predicateTransition = (PredicateTransition)transition;\n\t\t\t\tif (!sempred(_ctx, predicateTransition.ruleIndex, predicateTransition.predIndex)) {\n\t\t\t\t\tthrow new FailedPredicateException(this);\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase Transition.ACTION:\n\t\t\t\tActionTransition actionTransition = (ActionTransition)transition;\n\t\t\t\taction(_ctx, actionTransition.ruleIndex, actionTransition.actionIndex);\n\t\t\t\tbreak;\n\n\t\t\tcase Transition.PRECEDENCE:\n\t\t\t\tif (!precpred(_ctx, ((PrecedencePredicateTransition)transition).precedence)) {\n\t\t\t\t\tthrow new FailedPredicateException(this, String.format(\"precpred(_ctx, %d)\", ((PrecedencePredicateTransition)transition).precedence));\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new UnsupportedOperationException(\"Unrecognized ATN transition type.\");\n\t\t}\n\n\t\tsetState(transition.target.stateNumber);\n\t}\n\n\t/** Method visitDecisionState() is called when the interpreter reaches\n\t *  a decision state (instance of DecisionState). It gives an opportunity\n\t *  for subclasses to track interesting things.\n\t */\n\tprotected int visitDecisionState(DecisionState p) {\n\t\tint predictedAlt = 1;\n\t\tif ( p.getNumberOfTransitions()>1 ) {\n\t\t\tgetErrorHandler().sync(this);","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/ParserInterpreter.java#L271-L307","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\nparserInterpreter.expression(); // throws FailedPredicateException mid-parse\n\n// after\ntry { parserInterpreter.expression(); }\ncatch (FailedPredicateException e) {\n  errors.add(\"precedence predicate failed: \" + e.getMessage()\n    + \" at \" + e.getOffendingToken().getText());\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  parserInterpreter.startRule();\n} catch (FailedPredicateException e) {\n  // message is 'precpred(_ctx, N)'; ctx and offending token identify the spot\n  errors.add(e.getMessage() + \" at line \" + e.getOffendingToken().getLine());\n}","preventionTips":["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"],"tags":["antlr","parser-interpreter","precedence","left-recursion","atn"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}