{"record":{"id":"6c42e4b7d5143d7e","repo":"antlr/antlr4","slug":"parser-can-t-discover-a-lexer-to-use","errorCode":null,"errorMessage":"Parser can't discover a lexer to use","messagePattern":"Parser can't discover a lexer to use","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"runtime/Java/src/org/antlr/v4/runtime/Parser.java","lineNumber":480,"sourceCode":"\t * The preferred method of getting a tree pattern. For example, here's a\n\t * sample use:\n\t *\n\t * <pre>\n\t * ParseTree t = parser.expr();\n\t * ParseTreePattern p = parser.compileParseTreePattern(\"&lt;ID&gt;+0\", MyParser.RULE_expr);\n\t * ParseTreeMatch m = p.match(t);\n\t * String id = m.get(\"ID\");\n\t * </pre>\n\t */\n\tpublic ParseTreePattern compileParseTreePattern(String pattern, int patternRuleIndex) {\n\t\tif ( getTokenStream()!=null ) {\n\t\t\tTokenSource tokenSource = getTokenStream().getTokenSource();\n\t\t\tif ( tokenSource instanceof Lexer ) {\n\t\t\t\tLexer lexer = (Lexer)tokenSource;\n\t\t\t\treturn compileParseTreePattern(pattern, patternRuleIndex, lexer);\n\t\t\t}\n\t\t}\n\t\tthrow new UnsupportedOperationException(\"Parser can't discover a lexer to use\");\n\t}\n\n\t/**\n\t * The same as {@link #compileParseTreePattern(String, int)} but specify a\n\t * {@link Lexer} rather than trying to deduce it from this parser.\n\t */\n\tpublic ParseTreePattern compileParseTreePattern(String pattern, int patternRuleIndex,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLexer lexer)\n\t{\n\t\tParseTreePatternMatcher m = new ParseTreePatternMatcher(lexer, this);\n\t\treturn m.compile(pattern, patternRuleIndex);\n\t}\n\n\n\tpublic ANTLRErrorStrategy getErrorHandler() {\n\t\treturn _errHandler;\n\t}\n","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/Parser.java#L462-L498","documentation":"compileParseTreePattern(String, int) tries to auto-discover a Lexer by unwrapping the parser's token stream: getTokenStream().getTokenSource() must be a Lexer instance, because the pattern compiler lexes the pattern text with that same lexer grammar. If the token source is not a Lexer (e.g. a ListTokenSource or custom TokenSource), it throws UnsupportedOperationException. The overload taking an explicit Lexer never has this problem.","triggerScenarios":"Calling the two-argument compileParseTreePattern() on a parser fed by new CommonTokenStream(new ListTokenSource(tokens, name)); using a custom TokenSource implementation; calling it when getTokenStream() is null (parser not wired to a stream yet).","commonSituations":"Token-rewriting pipelines that reparse filtered tokens; test harnesses feeding synthetic token lists; pattern-matching utilities that accept any parser regardless of how its input was produced.","solutions":["Call the three-argument overload with the original lexer: parser.compileParseTreePattern(pattern, ruleIndex, lexer)","Keep a reference to the Lexer you created and pass it explicitly instead of relying on discovery","If discovery is required, ensure the parser's token stream is built directly over that Lexer (CommonTokenStream(lexer))"],"exampleFix":"// before\nparser.setTokenStream(new CommonTokenStream(listTokenSource));\nparser.compileParseTreePattern(\"<ID>\", R.rule); // throws\n\n// after\nparser.compileParseTreePattern(\"<ID>\", R.rule, myLexer); // explicit lexer","handlingStrategy":"validation","validationCode":"TokenSource src = parser.getTokenStream() != null ? parser.getTokenStream().getTokenSource() : null;\nif (src instanceof Lexer) {\n  pattern = parser.compileParseTreePattern(pat, ruleIndex);\n} else {\n  pattern = parser.compileParseTreePattern(pat, ruleIndex, knownLexer);\n}","typeGuard":"Lexer discoverLexer(Parser p) {\n  TokenSource s = p.getTokenStream() != null ? p.getTokenStream().getTokenSource() : null;\n  return (s instanceof Lexer) ? (Lexer) s : null;\n}","tryCatchPattern":null,"preventionTips":["Prefer the 3-arg compileParseTreePattern(pattern, ruleIndex, lexer) with an explicit Lexer","Check that the token stream's source is a Lexer before relying on auto-discovery","Keep the original Lexer reference when pipelines rewrap token sources"],"tags":["antlr","pattern-matching","lexer","token-source","unsupported-operation"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}