代码之家  ›  专栏  ›  技术社区  ›  Pavel Shved

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

  •  4
  • Pavel Shved  · 技术社区  · 6 年前

    如果有一个程序可以自动将Perl代码转换为python代码,使生成的python程序与原来的程序一样可读和可维护,更不用说以同样的方式工作了,那就太好了。

    最明显的解决方案就是 perl 通过python实用程序:

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

    然而,结果代码并不是一个Python代码,它本质上是一个Perl代码。潜在的转换器应该将Perl构造和习惯用法转换为易于阅读的python代码,它应该保留变量和子例程的名称(即,结果不应该看起来模糊),并且不应该过度破坏WrokFlow。

    这样的转换显然非常困难。转换的硬度取决于Perl特性和语法结构的数量,这些特性和语法结构不具有易读性和未混淆的Python等价物。我相信大量的这些特性使得这种自动转换成为不可能的。 几乎 (同时) 理论的 可能性存在)。

    那么,您能说出不能像最初的Perl代码那样简洁地用Python表示的Perl习语和语法特性吗?

    编辑 :一些人将python链接到perl converters,并在此基础上推断,将perl写入python也应该很容易。不过,我相信 到蟒蛇 是在 更大的 需求;不过这个转换器还没有写出来——而反向的已经写出来了!这只会让我对编写一个好的Python转换程序的不可能更加有信心。

    11 回复  |  直到 13 年前
        1
  •  17
  •   Eric Strom    14 年前

    只需在这里的其他一些列表上进行扩展,这些Perl构造在Python中可能非常笨拙(如果可能的话)。

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

    这个列表一直持续下去,有人可以尝试在所有类似的构造之间创建一个映射,但最终它会因为一个简单的原因而失败。

    无法静态分析Perl。Perl代码中的定义(尤其是begin块中的定义)改变了编译器解释剩余代码的方式。因此,对于非琐碎的程序,从perl=>python进行转换会遇到停止问题。

    在程序完成运行之前,无法确切地知道如何编译所有程序,并且理论上可以创建一个Perl程序,该程序每次运行时都会进行不同的编译。这意味着一个Perl程序可以映射到无限多的python程序,正确的方法只有在Perl解释器中运行原始程序之后才能知道。

        2
  •  34
  •   corsiKa    14 年前

    你最好的Perl-to-python转换器大概23岁,刚从大学毕业,正在找工作。

        3
  •  25
  •   S.Lott    14 年前

    为什么Perl不是Python。

    1. Perl的语句或多或少都是Python所缺少的。虽然您可以设计匹配语句,但语法与Perl完全不同,因此很难称之为“翻译”。你真的需要烹饪一些精美的python东西,使它像最初的perl一样简洁。

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

    3. Perl的数据结构与python的数据结构完全不同,因此很难进行转换。

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

    一个2的例子就足够了。

    Perl:

    do_something || die()
    

    哪里有东西? 任何 任何形式的声明。

    要自动将其转换为python,必须将 || die() 语句在

    try:
       python_version_of_do_something
    except OrdinaryStatementFailure, e:
       die()
       sys.exit()
    

    其中比较常见的公式

    珀尔

    do_something
    

    会变成这样,使用简单的——不思考的——源代码的翻译

    try:
       python_version_of_do_something
    except OrdinaryStatementFailure, e:
       pass
    

    当然,

    珀尔

    do_this || do_that || die()
    

    更复杂的是转换成python。

    珀尔

    do_this && do_that || die()
    

    真的很有说服力。我的Perl已经生锈了,所以我记不起这种东西的精确语义。但是您必须完全理解语义才能计算出一个pythonic实现。

    python示例不是 好的 蟒蛇。写 好的 python需要“思考”,这是自动翻译无法做到的。

    每一个Perl构造都必须像那样被“包装”,以便把最初的Perl语义变成一种pythonic形式。

    现在,对 每一个 Perl的特性。

        4
  •  7
  •   NullUserException Mark Roddy    14 年前

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

    顺便问一下,有 Perthon 一个python到perl的转换程序。似乎没人愿意做一个走另一条路的人。

    编辑:我想我可能已经找到了为什么从Python到Perl的转换器更容易实现的原因。这是因为python允许您处理脚本的ast。见 parser module.

        5
  •  5
  •   ysth    14 年前

    在编译Perl代码的过程中,可以通过实验构建Perl来收集额外的信息(例如,注释),甚至可以将结果作为XML发出。除了以下情况外,似乎没有任何有关此问题的文档: http://search.cpan.org/perldoc/perl5100delta#MAD

    这将有助于构建一个翻译程序。我希望你能很容易地得到80%的路,95%的路非常困难,而且永远不会比这更好。有太多的东西不能很好地映射。

        6
  •  5
  •   David Thornley    14 年前

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

    一个程序的意义可以由语言定义精确地定义,但是程序员不一定需要所有的细节。C程序员测试值A printf() 返回的is负数是检查错误条件,通常不关心确切的值。 if (printf("%s","...") < 0) exit(); 可以翻译成Perl print "..." or die(); . 这些语句的含义可能并不完全相同,但它们通常是程序员的意思,为了从惯用Perl或C代码创建惯用C或Perl代码,转换器必须考虑到这一点。

    由于不同的计算机语言对于相似的事物有着不同的语义,所以通常不可能将一种语言翻译成另一种语言,并以可读的形式给出完全相同的含义。为了创建可读的代码,翻译器需要理解程序员打算做什么,这是非常困难的。

    此外,从python转换为perl比从perl转换为python更容易。python是一种直截了当的语言,有明确的标准方法来做事情,而perl是一种过于复杂的语言,它的座右铭是“有不止一种方法可以做到这一点”。将python表达式转换为无数个对应的perl表达式之一比弄清perl程序员的意思和表达在蟒蛇中。

        7
  •  3
  •   Paul Nathan    14 年前
    • python范围和名称空间是 不同的 从Perl。

    • 在Python中,一切都是一个对象。在Perl中,引擎盖下的所有内容似乎都是一个列表/哈希/标量/引用/函数。这就产生了不同的设计方法和习惯用法。

    • Perl有匿名代码块,可以使用一些分支即时生成闭包。我是 漂亮的 当然这不是Python特性。

    我确实认为一个非常聪明的人可以静态地分析大量的Perl并生成一个程序,该程序使用小型Perl程序并输出执行相同任务的Python程序。

    我更怀疑大型和/或粗糙的Perl翻译的可行性。我们中的一些人有时会写一些非常奇怪的代码……:)

        8
  •  2
  •   Hynek -Pichi- Vychodil    14 年前

    这是不可能的,因为您甚至不能正确地解析Perl代码。见 Perl Cannot Be Parsed: A Formal Proof 了解更多详细信息。

        9
  •  1
  •   Jon Purdy    14 年前

    这个 B Malcolm Beattie的模块集将是此类问题唯一明智的出发点,尽管我有其他答案,因为这将是一个难以解决的问题。一般来说,将一种高级语言的意义翻译成另一种高级语言需要一个高级翻译,而目前,这可能意味着 只有 一个人。

    这个问题的困难,因为 任何 这对语言,是由于所讨论语言的本质上的根本性差异,例如运行时语义和公共习语,更不用说库了。

        10
  •  1
  •   Thorbjørn Ravn Andersen    13 年前

    从一种高级语言到另一种高级语言几乎不可能创建通用翻译程序,原因是程序只描述 同质光波导 (这是源代码中注释的原因)。

    为了用另一种高级语言创建一个有意义的程序,你(或翻译程序)需要知道 为什么? 能够创建最好的程序。如果您不能做到这一点,那么您所能做的就是为Perl程序的编译版本创建一个Python解释器。

    换句话说,要正确地完成这项工作,你需要走出盒子,这对于计算机来说是非常困难的。

        11
  •  0
  •   Ryan M Jordan    14 年前

    nullUserException基本上总结了它-它当然 可以 做吧,这将是一项巨大的努力。我见过一些语言转换实用程序编译为中间语言(如.NET的CIL),然后将其解压缩为所需的语言。从Perl到Python,我还没有见过。但是,您可以找到一个python-to-perl转换器。 here 不过,除非你想创建自己的网站,否则这对你可能没什么用处,在这种情况下,它可能会提供一些有用的参考。

    编辑:如果您只需要Python脚本中的确切功能, PyPerl 可能对你有用。