为什么不可能创建一个实用的Perl到Python源代码转换器?

P S*_*ved 4 python perl

如果存在一个自动将Perl代码转换为Python代码的程序,那么这将是很好的,这使得生成的Python程序可以像原始代码一样可读和可维护,更不用说以相同的方式工作了.

最明显的解决方案是perl通过Python utils 调用:

#!/usr/bin/python
os.exec("tail -n -2 "+__file__+" | perl -")
...the rest of file is the original perl program...
Run Code Online (Sandbox Code Playgroud)

但是,结果代码几乎不是Python代码,它本质上是一个Perl代码.潜在的转换器应该将Perl结构和习语转换为易于阅读的Python代码,它应该保留变量和子程序名称(即结果不应该看起来模糊)并且不应该过多地破坏wrokflow.

这样的转换显然非常困难.转换的硬度取决于Perl特性和语法结构的数量,这些特征和语法结构没有易于阅读,未经过混淆的Python等价物.我相信大量的这样的特征使得这种自动转换实际上是不可能的 (理论上存在可能性).

那么,您能否将Perl惯用语和语法功能命名为无法在Python中表达为原始Perl代码中的简洁?

编辑:有些人将Python-to-Perl召集人联系起来,并在此基础上推断出,编写Perl-to-Python也应该很容易.不过,我敢肯定,转换到Python是在更大的需求; 仍然没有写这个转换器 - 而反过来已经!这让我对不可能为Python编写好的转换器更加坚定.

cor*_*iKa 34

你最好的Perl to Python转换器可能已有23年历史,刚毕业大学并正在寻找工作.

  • 如果没有有用的贡献,你就会把一个严肃的问题变成一个小小的笑话. (11认同)
  • @Evan:不过,这可能是真的. (2认同)

S.L*_*ott 25

为什么Perl不是Python.

  1. Perl有Python或多或少完全缺乏的语句.虽然您可以设计匹配语句,但语法将完全不同于Perl,因此很难将其称为"翻译".你真的必须做一些花哨的Python东西,使它像原来的Perl一样简洁.

  2. Perl具有与Python不同的运行时语义,使得翻译非常具有挑战性.我们将在下面看一个例子.

  3. Perl的数据结构与Python相差甚远,翻译很难.

  4. 默认情况下,Perl线程不共享数据.只能共享选定的数据元素.Python线程有更常见的"共享所有"数据.

#2的一个例子就足够了.

Perl的:

do_something || die()
Run Code Online (Sandbox Code Playgroud)

do_something在哪里是任何类型的陈述.

要自动将其转换为Python,您必须将每个|| die()语句包装在其中

try:
   python_version_of_do_something
except OrdinaryStatementFailure, e:
   die()
   sys.exit()
Run Code Online (Sandbox Code Playgroud)

哪里比较常见的配方

Perl的

do_something
Run Code Online (Sandbox Code Playgroud)

将成为这使用简单 - 不假思索 - 源的翻译

try:
   python_version_of_do_something
except OrdinaryStatementFailure, e:
   pass
Run Code Online (Sandbox Code Playgroud)

而且当然,

Perl的

do_this || do_that || die()
Run Code Online (Sandbox Code Playgroud)

翻译成Python更加复杂.

Perl的

do_this && do_that || die()
Run Code Online (Sandbox Code Playgroud)

真的很有信心.我的Perl生锈了,所以我不记得这种事情的确切语义.但是你必须完全理解语义来解决Pythonic实现.

Python示例不是很好的 Python.要写出好的 Python的需要"思考",一些自动翻译无法做到的.

并且每个Perl构造都必须像这样"包装",以便将原始的Perl语义变为Pythonic形式.

现在,对Perl的每个功能进行类似的分析.

  • 稻草人,有人吗?Python易于阅读.阅读用Perl编写的Python并不容易. (16认同)
  • @DVK:你完全错过了这一点.所以我修改了答案以试图澄清它.**不假思索**,**自动**将Perl翻译成Python会导致问题.只需要一小部分真正的人类**思考**,就可以获得更好,更清晰的Pythonic陈述.但问题不在于**思考**,人类翻译.它是关于**不假思索**,**自动**翻译. (2认同)
  • 即使只有几次尝试,你也不会死于perl方式:在eval之外,将LIST的值打印到STDERR并以$!的当前值退出.如果$!为0时,以($?>> 8)的值退出.如果($?>> 8)为0,则退出255.在eval()中,错误消息被填充到$ @中,并且eval以未定义的值终止.如果LIST的最后一个元素不以换行符结尾,则还会打印当前脚本行号和输入行号(如果有),并提供换行符.如果输出为空且$ @已包含值,则在追加后重复使用该值. (2认同)

Eri*_*rom 17

为了扩展这里的一些其他列表,这些是一些在python中可能非常笨拙的Perl构造(如果可能的话).

  • 动态范围(通过local关键字)
  • typeglob操作(具有相同名称的多个变量)
  • 格式(它们都有自己的语法)
  • 关于可变变量的闭包
  • 编译指示
  • 左值子程序(mysub() = 5;类型代码)
  • 源过滤器
  • context(list vs scalar,以及调用代码可以检查它的方式wantarray)
  • 类型强制/动态类型
  • 任何使用字符串的程序 eval

列表继续,有人可以尝试在所有类似的构造之间创建映射,但最终它将是一个简单的原因失败.

Perl无法进行静态解析.Perl代码中的定义(特别是BEGIN块中的定义)改变了编译器解释剩余代码的方式.因此,对于非平凡的程序,从Perl => Python的转换会遇到暂停问题.

在程序运行完成之前,没有办法确切地知道所有程序的编译方式,理论上可以创建一个Perl程序,每次运行时都会以不同方式编译.这意味着一个Perl程序可以映射到无限数量的Python程序,只有在perl解释器中运行原始程序后才能知道它的正确性.

  • XS是另一个棘手的问题,尽管它模糊了它是否真的是"Perl". (3认同)
  • @Pavel =>我认为你低估了问题的范围.虽然我的答案中的思想练习无疑是一个边缘情况,但Perl程序中的每个"sub ... {}"定义都有一个隐含的"BEGIN"块.和每个`use`语句一样."BEGIN {*{(caller).":: $ _"} = sub {...}的简单示例,用于qw(名称列表)}`违反任何类型的静态解析(并且该模式是相当普遍的做法(从模块中导出子程序就是这样完成的)).并且每个声明都可以完全改变解析以下代码的方式. (3认同)
  • @Pavel =>考虑尝试解析以下语句`my @result = foo bar 1,2,3;`.如果`foo`有一个`(@)`原型,而`bar`有一个`($)`原型,那么该语句就会解析为`my @result = foo(bar(1),2,3)`.但是,如果`foo`有一个`($)`原型,它就像这个`(我的@result = foo(bar(1))),2,3;`,如果它们都有`(@) `prototypes,`我的@result = foo(bar(1,2,3));`.正如您所看到的,这里的原型只能完全改变其裸字所在行的解析方式.并且随着更多原型的添加,这些解析规则可以来回变化. (3认同)
  • ...如果事实证明原型子是以编程方式添加的(这不是闻所未闻的,没有一种方法可以在Perl中导出subs,你可以使用Exporter,或者编写自己的方法),没有办法静态地确定它们将是什么,因此无法准确地继续使用引入它们的BEGIN块之外的解析.自我变异解析器规则的这个问题是自动代码转换的主要障碍之一,因为它为语句"只有perl可以解析Perl"(小p是解释器二进制)提供了真理. (2认同)

Nul*_*ion 7

这不是不可能的,只需要做很多工作.

顺便说一下,有一个Python-to-Perl翻译器Perthon.似乎没有人愿意制造另一种方式.

编辑:我想我可能已经找到了为什么Python to Perl转换器更容易实现的原因.这是因为Python可以让你摆弄脚本的AST.请参阅解析器模块.

  • 编写一个从英文翻译成中文的程序需要花费大量精力才是同样的原因. (9认同)
  • @Pavel:自然语言在技术上应该比正式语言更容易*翻译,因为正式语言不需要有任何基本的相似性,而自然语言是,或者至少在实践中. (4认同)
  • @NullUser,*为什么*相同?目前尚不清楚自然语言翻译如何与正式语言的处理相关. (2认同)

yst*_*sth 5

可以通过实验构建Perl,以便在编译perl代码期间收集其他信息(例如注释),甚至可以将结果作为XML发出.除了以下内容之外,似乎没有任何关于此文档的文档:http://search.cpan.org/perldoc/perl5100delta#MAD

这应该有助于构建翻译.我希望你能够轻松地获得80%的成功率,95%的成功率很高,而且从来没有比这更好.有太多东西没有很好地映射.

  • 一些:打包和解压缩,格式化,左值子串,闭包,本地() (3认同)

Dav*_*ley 5

从根本上说,这是两种不同的语言.从一个转换为另一个并且结果大部分可读将意味着软件必须能够识别并生成代码习语,并且能够进行一些静态分析.

程序的含义可以由语言定义精确定义,但程序员不一定需要所有细节.AC程序员测试printf()返回的值是否为负是检查错误情况,并且通常不关心确切的值. if (printf("%s","...") < 0) exit();可以翻译成Perl as print "..." or die();.这些陈述可能并不完全相同,但它们通常是程序员的意思,并且从惯用的Perl或C代码创建惯用的C或Perl代码,翻译者必须考虑到这一点.

由于不同的计算机语言对于类似的事物往往具有不同的轻微语义,因此通常不可能将一种语言翻译成另一种语言并以可读的形式提出完全相同的含义.为了创建可读代码,翻译人员需要了解程序员打算做什么,这真的很难.

此外,将Python从Perl转换为Perl而不是Perl更容易.Python是一种直截了当的语言,具有明确的标准方法,而Perl是一种过于复杂的语言,其座右铭是"有多种方法可以做到".将Python表达式转换为无数相应的Perl表达式之一比确定Perl程序员的意思并在Python中表达它更容易.