{"record":{"id":"7b63a8a57b0d0c8e","repo":"antlr/antlr4","slug":"the-current-recognizer-does-not-provide-a-list-of-7b63a8","errorCode":null,"errorMessage":"The current recognizer does not provide a list of token names.","messagePattern":"The current recognizer does not provide a list of token names\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"runtime/Python3/src/antlr4/Recognizer.py","lineNumber":56,"sourceCode":"        rvmajor, rvminor = self.extractVersion(runtimeVersion)\n        tvmajor, tvminor = self.extractVersion(toolVersion)\n        if rvmajor!=tvmajor or rvminor!=tvminor:\n            print(\"ANTLR runtime and generated code versions disagree: \"+runtimeVersion+\"!=\"+toolVersion)\n\n    def addErrorListener(self, listener):\n        self._listeners.append(listener)\n\n    def removeErrorListener(self, listener):\n        self._listeners.remove(listener)\n\n    def removeErrorListeners(self):\n        self._listeners = []\n\n    def getTokenTypeMap(self):\n        tokenNames = self.getTokenNames()\n        if tokenNames is None:\n            from .error.Errors import UnsupportedOperationException\n            raise UnsupportedOperationException(\"The current recognizer does not provide a list of token names.\")\n        result = self.tokenTypeMapCache.get(tokenNames, None)\n        if result is None:\n            result = zip( tokenNames, range(0, len(tokenNames)))\n            result[\"EOF\"] = Token.EOF\n            self.tokenTypeMapCache[tokenNames] = result\n        return result\n\n    # Get a map from rule names to rule indexes.\n    #\n    # <p>Used for XPath and tree pattern compilation.</p>\n    #\n    def getRuleIndexMap(self):\n        ruleNames = self.getRuleNames()\n        if ruleNames is None:\n            from .error.Errors import UnsupportedOperationException\n            raise UnsupportedOperationException(\"The current recognizer does not provide a list of rule names.\")\n        result = self.ruleIndexMapCache.get(ruleNames, None)\n        if result is None:","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Python3/src/antlr4/Recognizer.py#L38-L74","documentation":"Recognizer.getTokenTypeMap() builds a token-name-to-type dictionary (required by XPath and tree-pattern compilation) and raises UnsupportedOperationException when getTokenNames() returns None. Generated parsers populate tokenNames; hand-written or partially configured recognizers leave it None, and this guard fires the first time a name-based lookup is attempted.","triggerScenarios":"Calling getTokenTypeMap(), XPath.evaluate(), or compileParseTreePattern() on a Parser/Recognizer whose tokenNames attribute is None; constructing a bare Recognizer subclass without generated metadata; custom parser wrappers that drop the generated fields.","commonSituations":"Hand-written recognizers used with ANTLR tree utilities; runtime/generated-code version mismatch where the tokenNames field name or initialization changed; refactors that bypass generated __init__ paths.","solutions":["Use the tool-generated recognizer class, which sets tokenNames from the grammar's token vocabulary","For custom recognizers, assign self.tokenNames = [...] (ordered by token type) before calling name-based APIs","Verify tool/runtime version alignment if generated code suddenly lacks tokenNames after an upgrade"],"exampleFix":"# before\nclass MyParser(Parser):\n    tokenNames = None  # getTokenTypeMap() raises\n\n# after\nclass MyParser(Parser):\n    tokenNames = [\"<INVALID>\", \"ID\", \"INT\", \"PLUS\", \"EOF\"]  # indexed by token type","handlingStrategy":"type-guard","validationCode":"# Python: check names exist before name-based APIs\nif recognizer.getTokenNames() is None:\n    raise ValueError(\"recognizer has no token names; use a generated parser\")\nttype = recognizer.getTokenTypeMap()[\"ID\"]","typeGuard":"# Python\ndef has_token_names(recognizer) -> bool:\n    return recognizer.getTokenNames() is not None","tryCatchPattern":"try:\n    m = recognizer.getTokenTypeMap()\nexcept UnsupportedOperationException as ex:\n    if \"list of token names\" in str(ex):\n        # regenerate the recognizer or populate tokenNames before retry\n        raise\n    raise","preventionTips":["Use generated recognizer classes for XPath and tree-pattern features","Set tokenNames explicitly when hand-writing recognizers","Regenerate code after tool upgrades so metadata fields stay populated"],"tags":["antlr","python","recognizer","token-names","xpath"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}