{"record":{"id":"71765ff4f8700273","repo":"antlr/antlr4","slug":"a-lexer-interpreter-can-only-be-created-for-a-lexe","errorCode":null,"errorMessage":"A lexer interpreter can only be created for a lexer or combined grammar.","messagePattern":"A lexer interpreter can only be created for a lexer or combined grammar\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"tool/src/org/antlr/v4/tool/Grammar.java","lineNumber":1319,"sourceCode":"\t\t\t\tstateToGrammarRegionMap.put(n.atnState.stateNumber, tokenRegion);\n\t\t\t}\n\t\t}\n\t\treturn stateToGrammarRegionMap;\n\t}\n\n\t/** Given an ATN state number, return the token index range within the grammar from which that ATN state was derived. */\n\tpublic Interval getStateToGrammarRegion(int atnStateNumber) {\n\t\tif ( stateToGrammarRegionMap==null ) {\n\t\t\tstateToGrammarRegionMap = getStateToGrammarRegionMap(ast, null); // map all nodes with non-null atn state ptr\n\t\t}\n\t\tif ( stateToGrammarRegionMap==null ) return Interval.INVALID;\n\n\t\treturn stateToGrammarRegionMap.get(atnStateNumber);\n\t}\n\n\tpublic LexerInterpreter createLexerInterpreter(CharStream input) {\n\t\tif (this.isParser()) {\n\t\t\tthrow new IllegalStateException(\"A lexer interpreter can only be created for a lexer or combined grammar.\");\n\t\t}\n\n\t\tif (this.isCombined()) {\n\t\t\treturn implicitLexer.createLexerInterpreter(input);\n\t\t}\n\n\t\tList<String> allChannels = new ArrayList<String>();\n\t\tallChannels.add(\"DEFAULT_TOKEN_CHANNEL\");\n\t\tallChannels.add(\"HIDDEN\");\n\t\tallChannels.addAll(channelValueToNameList);\n\n\t\t// must run ATN through serializer to set some state flags\n\t\tIntegerList serialized = ATNSerializer.getSerialized(atn);\n\t\tATN deserializedATN = new ATNDeserializer().deserialize(serialized.toArray());\n\t\treturn new LexerInterpreter(\n\t\t\t\tfileName,\n\t\t\t\tgetVocabulary(),\n\t\t\t\tArrays.asList(getRuleNames()),","sourceCodeStart":1301,"sourceCodeEnd":1337,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/tool/src/org/antlr/v4/tool/Grammar.java#L1301-L1337","documentation":"Grammar.createLexerInterpreter(CharStream) builds a LexerInterpreter for a grammar, but a pure parser grammar (type PARSER, with an imported/external token file) has no lexer ATN to interpret, so it throws IllegalStateException. Combined grammars delegate to their implicit lexer.","triggerScenarios":"Calling g.createLexerInterpreter(input) where g.getType() == GrammarType.PARSER (grammar created from a parser-only .g4 with a TOKENS file or separate lexer grammar).","commonSituations":"Loading grammars via GrammarTool/ANTLRStringStorage at runtime and assuming every grammar can drive an interpreter; testing pipelines that uniformly call both createLexerInterpreter and createParserInterpreter on whatever grammar was loaded.","solutions":["Branch on grammar type: only call createLexerInterpreter when g.isLexer() or g.isCombined()","For a parser grammar, load its companion lexer grammar instead and interpret that","Consider the GrammarSpec API: check g.getType() first"],"exampleFix":"// before\nLexerInterpreter lex = g.createLexerInterpreter(charStream);\n\n// after\nLexerInterpreter lex;\nif (g.isParser() && !g.isCombined()) {\n    g = loadLexerGrammarFor(g); // separate lexer .g4\n}\nlex = g.createLexerInterpreter(charStream);","handlingStrategy":"type-guard","validationCode":"boolean canLex = g.isLexer() || g.isCombined();","typeGuard":"static boolean supportsLexerInterpreter(Grammar g) { return !g.isParser() || g.isCombined(); }","tryCatchPattern":"try { g.createLexerInterpreter(input); } catch (IllegalStateException e) { /* load the companion lexer grammar instead */ }","preventionTips":["Branch interpreter creation on Grammar.getType()","Keep lexer and parser grammar files together so the companion can be loaded"],"tags":["antlr","grammar","interpreter","java"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}