如何在Python tree-sitter 0.23.0中加载自定义语言
在Python tree-sitter 0.23.0中加载自定义语言共享对象
在tree-sitter Python绑定0.21.3及更早版本中,加载自定义语言的方式如下:
from tree_sitter import Language, Parser lang_path = "tree-sitter-test-lang/test-lang.so" # 加载语言 TESTLANG_LANGUAGE = Language(lang_path, 'testlang') # 初始化解析器并设置语言 parser = Parser() parser.set_language(TESTLANG_LANGUAGE) # 解析代码 source_code = b""" let x = 10; print x; """ tree = parser.parse(source_code) # 遍历语法树 root_node = tree.root_node def print_node(node, indent=""): print(f"{indent}{node.type}: {node.text.decode('utf-8')}") for child in node.children: print_node(child, indent + " ") print_node(root_node)
但到了0.23.0版本,API发生了较大变更:Language类需要接收tree-sitter.language类型的参数,Parser直接用Language实例初始化,build_library、set_language等方法被移除。官方给出的内置语言示例如下:
import tree_sitter_python as tspython from tree_sitter import Language, Parser PY_LANGUAGE = Language(tspython.language()) parser = Parser(PY_LANGUAGE) tree = parser.parse( bytes( """ def foo(): if bar: baz() """, "utf8" ) )
要在0.23.0版本中加载自定义生成的共享对象(比如tree-sitter-test-lang/test-lang.so),可以借助ctypes加载共享库,并获取其中的language函数返回值,再传入Language类完成初始化,完整代码如下:
import ctypes from tree_sitter import Language, Parser lang_path = "tree-sitter-simple-lang/simple-lang.so" # 加载自定义语言的共享对象 lib = ctypes.cdll.LoadLibrary(lang_path) # 获取language函数(tree-sitter生成的共享库会导出该函数) lib.language.restype = ctypes.c_void_p language_ptr = lib.language() # 初始化Language实例 my_language = Language(language_ptr) # 创建解析器并解析代码 parser = Parser(my_language) source_code = b""" let x = 10; print x; """ tree = parser.parse(source_code) # 遍历并打印语法树 root_node = tree.root_node def print_node(node, indent=""): print(f"{indent}{node.type}: {node.text.decode('utf-8')}") for child in node.children: print_node(child, indent + " ") print_node(root_node)
关键说明:
- 自定义tree-sitter语言编译生成的共享库会默认导出
language函数,该函数返回TSLanguage指针,对应Python绑定中的tree-sitter.language类型 - 使用
ctypes加载共享库后,需要指定language函数的返回类型为ctypes.c_void_p,确保指针被正确传递 - 最后将获取到的指针传入
Language类,即可创建符合新版本要求的语言实例,进而初始化解析器
内容的提问来源于stack exchange,提问作者Ben Mulongo
相关产品推荐
相关产品推荐

