针对.pyc文件的编译器?

时间:2009-10-20 03:53:17

标签: python compiler-construction pyc

出于好奇,是否有许多针对.pyc个文件的编译器?

经过一段谷歌搜索后,我能找到的只有两个:

  • unholy:why_的Ruby-to-pyc编译器
  • Python:PSF的Python到pyc编译器

所以......还有吗?

(作为旁注,我考虑过这个因为我想写一个Scheme-to-pyc编译器)

(作为第二个注释,我并没有任何幻想,一个Scheme-to-pyc编译器会有用,但它会给我一个令人难以置信的借口来学习两者的内部结构Scheme和Python)

5 个答案:

答案 0 :(得分:4)

“我想写一个Scheme-to-pyc编译器”。

我的大脑疼!你为什么想这么做? Python字节代码是一种专门设计用于满足Python语言需求的中间语言,旨在在Python虚拟机上运行,​​而Python虚拟机也是根据Python的需求量身定制的。如今,Python开发的一些最重要的领域是将Python转移到其他“虚拟机”,例如Jython(JVM),IronPython(.NET),PyPy和{ {3}}项目(将CPython移动到基于Unladen Swallow的表示)。试图将另一种非常不同的语言(Scheme)的语法和语义压缩到另一种高级语言的中间表示中似乎是在错误的级别上攻击问题(无论问题是什么)。所以,一般来说,似乎没有很多.pyc编译器,并且有充分的理由。

答案 1 :(得分:3)

几年前我编写了一个编译器,它接受了一种名为“Noodle”的类似lisp的语言并生成了Python字节码。虽然它从未变得特别有用,但它对于更好地理解Common Lisp(我复制了它的几个特性)以及更好地理解Python是一个非常好的学习经验。

我可以想到两种特殊情况,即直接定位Python字节码可能有用,而不是生成Python并将其传递给Python编译器:

  1. 完全闭包:在3.0之前的Python中(在nonlocal关键字之前),你不能在不诉诸字节码hackery的情况下修改已关闭的变量的值。您可以改为改变值,因此通常的做法是使用闭包引用列表,例如,从内部作用域更改其中的第一个元素。这真的很烦人。但是,限制是语法的一部分,而不是Python VM。我的语言有明确的变量声明,因此它成功地提供了“正常”闭包,并具有可修改的闭合值。
  2. 获取traceback对象而不引用任何内置函数。真正的利基案例,当然,但我用它打破了早期版本的“safelite”监狱。请参阅my posting
  3. 所以,是的,这可能比它的价值更多,但我很喜欢,你也可能。

答案 2 :(得分:2)

我建议你专注于CPython。

http://www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html

我建议您编写一个Scheme to Python translator,然后让CPython处理转换为.pyc,而不是Scheme to .pyc转换器。 (有这样做的先例;第一个C ++编译器是Cfront,它将C ++转换为C,然后让系统C编译器完成其余的工作。)

根据我对Scheme的了解,将Scheme转换为Python并不困难。

一个警告:Python虚拟机可能不像Scheme本身那样快。例如,Python不会自动将尾递归转换为迭代;并且Python具有相对较浅的堆栈,因此您实际上需要将尾递归转换为您的翻译器的迭代。

作为奖励,一旦Unladen Swallow加速Python,您的Scheme-to-Python翻译器将受益,并且在那时甚至可能变得实用!

如果这对你来说似乎是一个有趣的项目,我会说它。并非每个项目都必须立即实用。

P.S。如果你想要一个更实用的项目,你可能想要写一个AWK到Python翻译器。这样,拥有传统AWK脚本的人可以很容易地向Python跃进!

答案 3 :(得分:2)

为了您的兴趣,我已经编写了一个从简单的LISP到Python的玩具编译器。实际上,这是pyc编译器的LISP。

看看:sinC - The tiniest LISP compiler

答案 4 :(得分:1)

可能在聚会上有点晚了但是如果你仍然对clojure-py项目感兴趣(https://github.com/halgari/clojure-py)现在能够将一个重要的clojure子集编译成python字节码 - 但总是欢迎一些帮助。

目标字节码本身并不难,除了一件事:它在各个平台上都不稳定(例如,MAKE_FUNCTION在Python 3中从堆栈弹出2个元素,但在Python 2中只有1个),并且这些差异没有明确记录在一个地方(afaict) - 所以你可能需要一些抽象层。