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

  1. Add a public constructor with signature (Grammar, ATN, TokenStream) to your ParserInterpreter subclass that calls super(...)
  2. 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

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


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