python - 如何编译一个小的 DSL?
问题描述
我正在为 Python (3.x) 中的应用程序编写一个小的领域特定语言。目前该语言使用 Python 的解释器来运行脚本,但是我希望能够将代码编译成 Python 的字节码,以便我可以将它作为普通的 Python 模块导入。
有没有什么方法可以实现这一点,而无需将我的 DSL 代码转换为 Python 语法的步骤?
解决方案
为了编译成 Python 的字节码,你默认需要两(三)个东西:
-
如果不是为了使用,那么至少要与 AST 进行比较,如果你正确生成它,如果有东西丢失等等
(1.5) 您的 DSL 拆分为抽象语法树 (AST) - 这是 Python 在您运行(即甚至导入)代码/文件时默认执行的操作。
您可以做的是将您的 DSL“编译”(翻译)为 AST 或正确的 Python 代码,然后您可以从那里使 Python 解释器(用于代码)或 Python 编译器(用于 AST)做您想做的事情,例如调用Python 的 C API 即使用 Python 作为 C 库,而不是将解释器作为二进制文件调用。
对于 C API从这里开始,但目前我找不到编译器的任何参考,因此以“虚拟”方式,您可以简单地包含compile.h
(警告),然后使用compile.c
库中公开的函数。
如果没有,您将需要手动编译 Python(甚至可能对其进行修补),因此这些符号会被公开并且您可以使用它们。但是,这种方法有一个问题,那就是 - 不使用公共 Python 的 C API 最终可能会破坏您的功能(符号可能会更改名称、功能或干脆消失),因此如果选择这种方法,请编写测试并使用特定的提交,所以您“密封”您使用的版本,并在一段时间后提交,运行测试并查看它是否中断(然后修复)。
此外,这是一个混乱的话题,因为没有很多人尝试更改或至少访问默认编译器,但是:
- https://wiki.python.org/moin/AST
- https://greentreesnakes.readthedocs.io/en/latest/(好的 AST 文档)
- AST成绩单
- PyCon 2010 AST 主题
除此之外,请尝试联系 CPython 和 PyPy 维护者:
就像 PyPy 进行即时编译一样。但是 afaik他们的代码没有漂亮的界面,所以tar
这里grep -r '<keyword [keyword ...]> <file or folder>
是你的助手。
推荐阅读
- python - TypeError:“DiscreteFactor”对象不可下标
- javascript - Office 365 加载项中是否有任何事件或功能应在不打开加载项的情况下执行?
- laravel - 如何为管理员使用 Spatie 角色和权限?
- linux - 为什么这个 git/grep/vim 快捷方式 bash 代码不能像宣传的那样工作?
- ios - 如何在 Xamarin 中使用条件编译基于 XCODE 版本执行条件
- javascript - 如何在取消选择前一个元素的同时向新元素添加“选择”样式?
- ios - 标签栏控制器意外关闭行为
- javascript - Jquery/Ajax 使用 php 获取数据库
- flutter - Flutter:具有不同高度约束的水平 ListView 视图
- postgresql - 无法从另一个正在运行的 Docker 实例 CURL 到 Docker 容器(使用 Kafka 连接器)