antlr/antlr4 · error · IllegalStateException
A parser interpreter can only be created for a parser or com
Error message
A parser interpreter can only be created for a parser or combined grammar.
What it means
Grammar.createGrammarParserInterpreter(TokenStream) constructs a GrammarParserInterpreter (rule-name-aware subclass) but a lexer grammar has no parser rules or parser ATN, so it throws IllegalStateException immediately when this.isLexer().
Source
Thrown at tool/src/org/antlr/v4/tool/Grammar.java:1347
allChannels.addAll(channelValueToNameList);
// must run ATN through serializer to set some state flags
IntegerList serialized = ATNSerializer.getSerialized(atn);
ATN deserializedATN = new ATNDeserializer().deserialize(serialized.toArray());
return new LexerInterpreter(
fileName,
getVocabulary(),
Arrays.asList(getRuleNames()),
allChannels,
((LexerGrammar)this).modes.keySet(),
deserializedATN,
input);
}
/** @since 4.5.1 */
public GrammarParserInterpreter createGrammarParserInterpreter(TokenStream tokenStream) {
if (this.isLexer()) {
throw new IllegalStateException("A parser interpreter can only be created for a parser or combined grammar.");
}
// must run ATN through serializer to set some state flags
IntegerList serialized = ATNSerializer.getSerialized(atn);
ATN deserializedATN = new ATNDeserializer().deserialize(serialized.toArray());
return new GrammarParserInterpreter(this, deserializedATN, tokenStream);
}
public ParserInterpreter createParserInterpreter(TokenStream tokenStream) {
if (this.isLexer()) {
throw new IllegalStateException("A parser interpreter can only be created for a parser or combined grammar.");
}
// must run ATN through serializer to set some state flags
IntegerList serialized = ATNSerializer.getSerialized(atn);
ATN deserializedATN = new ATNDeserializer().deserialize(serialized.toArray());
return new ParserInterpreter(fileName, getVocabulary(), Arrays.asList(getRuleNames()), deserializedATN, tokenStream);View on GitHub (pinned to 7d5770395b)
Solutions
- Guard with if (g.isLexer()) skip/return before calling the method
- Load the parser/combined grammar when you need a parser interpreter
Example fix
// before
GrammarParserInterpreter it = g.createGrammarParserInterpreter(tokens);
// after
if (g.isLexer()) throw new IllegalStateException("not a parser grammar");
GrammarParserInterpreter it = g.createGrammarParserInterpreter(tokens); Defensive patterns
Strategy: type-guard
Validate before calling
boolean canParse = !g.isLexer();
Type guard
static boolean supportsParserInterpreter(Grammar g) { return !g.isLexer(); } Try / catch
try { g.createGrammarParserInterpreter(tokens); } catch (IllegalStateException e) { /* skip: grammar is lexer-only */ } Prevention
- Check grammar type before calling interpreter factories
- Write harnesses that dispatch on g.getType()
When it happens
Trigger: Calling createGrammarParserInterpreter(tokens) on a Grammar loaded from a lexer-only grammar file (grammar type LEXER).
Common situations: Generic grammar-processing tooling that calls the interpreter factory on every loaded grammar without checking its type.
Related errors
- A lexer interpreter can only be created for a lexer or combi
- Unexpected data entry
- can't create parser to match incoming {parserClass}
- 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/c6ba311e103e932e.
Report an issue: GitHub.