antlr/antlr4 · error · IllegalArgumentException
can't create parser to match incoming {parserClass}
Error message
can't create parser to match incoming {parserClass} What it means
deriveTempParserInterpreter reflects on the incoming parser's class to find a (Grammar, ATN, TokenStream) constructor for subclasses of ParserInterpreter. If the subclass lacks that exact constructor (or construction fails), the reflective exception is wrapped in IllegalArgumentException naming the offending parser class.
Source
Thrown at tool/src/org/antlr/v4/tool/GrammarParserInterpreter.java:401
return trees;
}
/** Derive a new parser from an old one that has knowledge of the grammar.
* The Grammar object is used to correctly compute outer alternative
* numbers for parse tree nodes. A parser of the same type is created
* for subclasses of {@link ParserInterpreter}.
*/
public static ParserInterpreter deriveTempParserInterpreter(Grammar g, Parser originalParser, TokenStream tokens) {
ParserInterpreter parser;
if (originalParser instanceof ParserInterpreter) {
Class<? extends ParserInterpreter> c = originalParser.getClass().asSubclass(ParserInterpreter.class);
try {
Constructor<? extends ParserInterpreter> ctor = c.getConstructor(Grammar.class, ATN.class, TokenStream.class);
parser = ctor.newInstance(g, originalParser.getATN(), originalParser.getTokenStream());
}
catch (Exception e) {
throw new IllegalArgumentException("can't create parser to match incoming "+originalParser.getClass().getSimpleName(), e);
}
}
else { // must've been a generated parser
// IntegerList serialized = ATNSerializer.getSerialized(originalParser.getATN(), g.getLanguage());
// ATN deserialized = new ATNDeserializer().deserialize(serialized.toArray());
parser = new ParserInterpreter(originalParser.getGrammarFileName(),
originalParser.getVocabulary(),
Arrays.asList(originalParser.getRuleNames()),
originalParser.getATN(),
tokens);
}
parser.setInputStream(tokens);
// Make sure that we don't get any error messages from using this temporary parser
parser.setErrorHandler(new BailErrorStrategy());
parser.removeErrorListeners();
parser.removeParseListeners();View on GitHub (pinned to 7d5770395b)
Solutions
- Add a public constructor with signature (Grammar, ATN, TokenStream) to your ParserInterpreter subclass that calls super(...)
- Alternatively pass a plain generated parser or base ParserInterpreter, which takes the generated-parser branch and avoids reflection
Example fix
// before
class MyParserInterpreter extends ParserInterpreter {
MyParserInterpreter(Grammar g, ATN atn, TokenStream ts, ExtraConfig cfg) { super(g, atn, ts); }
}
// after
class MyParserInterpreter extends ParserInterpreter {
public MyParserInterpreter(Grammar g, ATN atn, TokenStream ts) { super(g, atn, ts); }
MyParserInterpreter(Grammar g, ATN atn, TokenStream ts, ExtraConfig cfg) { this(g, atn, ts); }
} Defensive patterns
Strategy: validation
Validate before calling
Constructor<?> ctor = parserClass.getConstructor(Grammar.class, ATN.class, TokenStream.class); // throws NoSuchMethodException if missing
Type guard
static boolean hasInterpreterCtor(Class<? extends ParserInterpreter> c) {
try { c.getConstructor(Grammar.class, ATN.class, TokenStream.class); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try { deriveTempParserInterpreter(g, parser, tokens); } catch (IllegalArgumentException e) { /* add (Grammar,ATN,TokenStream) ctor to subclass or pass base ParserInterpreter */ } Prevention
- Give every ParserInterpreter subclass a public (Grammar, ATN, TokenStream) constructor
- Prefer base ParserInterpreter or generated parsers when custom subclasses are not essential
When it happens
Trigger: Passing a custom ParserInterpreter subclass into deriveTempParserInterpreter (directly or via GrammarParserInterpreter.parseFromStartRule / profiling paths) when the subclass does not declare a public ParserInterpreter(Grammar, ATN, TokenStream) constructor.
Common situations: User-defined ParserInterpreter subclasses for instrumentation or error recovery that add constructors but forget the (Grammar, ATN, TokenStream) one, or make it non-public.
Related errors
- Unexpected data entry
- A lexer interpreter can only be created for a lexer or combi
- A parser interpreter can only be created for a parser or com
- replace op boundaries of ${rop} overlap with previous ${prev
- insert op ${iop} within boundaries of previous ${rop}
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/3b083f5dd62a11ab.
Report an issue: GitHub.