我可以从cppyy获取AST

问题描述 投票:1回答:1

我想在创建python绑定之前在cppyy中访问AST。我想用它来生成其他种类的绑定。

我见过cppyy-generator,但是它需要在计算机上单独安装clang。由于cppyy无需单独安装clang就可以进行JIT编译,因此我必须相信可以从底层的解释器中获取AST。有没有办法从cppyy获取此AST信息?

示例:

import cppyy

cppyy.cppdef("""
namespace foo
{
class Bar
{
public:
    void DoSomething() {}
};
}

""")

cppyy可以(非常)为我生成cppyy.gbl.foo.Bar。这意味着它必须使用Cling进行编译,获取AST并生成python。如何查看AST数据?

谢谢!

编辑:我可以看到我需要的很多信息都在cppyy-backend capi和cpp_cppyy文件中。但是,我的CPython foo不够强大,无法弄清楚如何调用它们以及如何从python脚本访问它们。

python abstract-syntax-tree cppyy
1个回答
0
投票

[b / c这里有两个歧义,相同的名称适用于不同的步骤和不同的位置。让我解释一下结构(和历史记录),甚至可以回答您的问题。

cppyy-generator使用Clang Python绑定。因此,它访问的AST是C ++版本,并且具有完整(丑陋)的外观。您不需要cppyy的任何部分即可使用Clang Python绑定。 cppyy-generator提供了一个特定的用例,您希望将所有本地C ++实体预加载到Python模块中。由于cppyy会利用惰性所有内容并自动加载,因此出于性能原因,“所有C ++实体”(本地或其他)的概念没有明确定义的含义。因此,使用了libclang,概念很明确。

cppyy后端capi(或C-API)是在还原中开发的API,用于服务cppyy的PyPy实现。它是C风格的API,用于引导cppyy / C ++。它简化为编写Python-C ++绑定的要点,隐藏了Clang AST的许多不相关细节(例如,可以在Clang AST中存在模板的15种左右方式被简化为“ IsTemplate”等)。后端C-API完全不依赖或使用Python。

后端C-API的实现不是很漂亮。部分原因是由于历史原因(不好的事情),部分原因是隐藏所有Cling以及Clang,以防止与可能使用Clang或LLVM的应用程序其他部分发生冲突(这是一件好事;正在使用的Clang版本) by Cling是自定义的,可能不适用于Numba)。同样,所有这些都与Python无关。

然后,在Python中使用它。有两种不同的实现:用于CPython的CPyCppyy(用C实现)和PyPy _cppyy模块(用RPython实现)。两者都执行了通过C-API从Python跨入C ++的计划。既不生成也不使用Python AST:直接生成和操纵Python实体。这很懒惰。请仔细考虑以下步骤:在上面的示例中,Python用户将键入类似cppyy.gbl.foo.Bar().DoSomething()的内容。在cppyy中,Python的__getattr__用于截取名称,然后仅通过后端到达Cling询问其是否知道fooBar等。例如,C-API GetScope("foo")将返回一个有效的标识符,因此CPyCppyy / _cppyy知道生成一个Python类来表示名称空间。但是,它绝不会完全扫描AST中的全局(甚至foo)名称空间以生成先验绑定。根据您的描述,CPyCppyy / _cppyy中没有任何有用的东西。

回到您的第一条语句,您要生成其他类型的绑定。您没有说明绑定的类型,但是选择C-API的主要原因是它位于Cling之上,而不是Clang,因为直接来自C ++或通过其Python绑定的Clang AST会。 Cling提供了对JIT的轻松访问,但是您也可以直接从Clang(其库而不是AST)对其进行编程。作为这种easyu访问的示例,在后端C-API中,您可以将要JITted的C ++字符串转储到compile函数中(此函数与您的示例中的cppdef完全相同)。 Cling员工有计划直接从Cling为动态语言提供更好的界面,但这是一项正在进行的工作,尚不可用(AFAIK)。

最后,请注意Cling contains Clang,因此,如果安装Cling,您仍然会获得Clang(和LLVM),这可能是一个严重的依赖项。

© www.soinside.com 2019 - 2024. All rights reserved.