大多数编程语言都是图灵完整的,这意味着可以用一种语言解决的任何任务都可以用另一种语言解决,甚至可以在图灵机上解决。那么为什么没有自动翻译器可以将程序从任何给定语言转换为任何其他语言呢?我已经看到过尝试两种语言的尝试,但是它们始终只能在一种语言的有限子集上工作,并且几乎不能用于转换实际项目。
至少在理论上,是否有可能在所有语言之间编写100%正确的翻译器?实践中有哪些挑战?是否有现有的翻译人员在工作?
大多数编程语言都是图灵完整的,这意味着可以用一种语言解决的任何任务都可以用另一种语言解决,甚至可以在图灵机上解决。那么为什么没有自动翻译器可以将程序从任何给定语言转换为任何其他语言呢?我已经看到过尝试两种语言的尝试,但是它们始终只能在一种语言的有限子集上工作,并且几乎不能用于转换实际项目。
至少在理论上,是否有可能在所有语言之间编写100%正确的翻译器?实践中有哪些挑战?是否有现有的翻译人员在工作?
Answers:
最大的问题不是程序代码的实际翻译,而是平台API的移植。
考虑使用PHP到Java的翻译器。做到不嵌入PHP二进制代码部分的唯一可行方法是用Java重新实现所有PHP模块和API。这涉及实现超过10.000个功能。与之相比,实际翻译语法的工作很容易。即使完成了所有这些工作,您也没有Java代码,但您还是会碰巧在Java平台上运行,但内部却像PHP那样结构化。
这就是为什么我想到的唯一此类工具都是翻译代码以进行部署,而不是随后进行维护。Google的GWT将Java“编译”为JavaScript。Facebook的嘻哈将PHP编译为C。
如果你有一个中间格式,那么你可以实现的东西,在语言转换X的程序,以这种格式,并且还从该格式语言Y.实现您感兴趣的所有语言的转换,就大功告成了,对不对?
好吧,你知道吗?这样的格式已经存在:汇编。编译器已经进行了“从X到汇编语言”的转换,并已将反汇编器转换为“从Y汇编语言”的转换。
现在,汇编不是进行反向转换的好语言,但是MSIL实际上并不是那么糟糕。下载Reflector,您将看到可以将.NET程序集反汇编为多种不同语言的选项(插件提供了更多选择)。因此,很有可能使用C#编写程序,将其编译为DLL(即MSIL),然后使用反射器将其反汇编为VB,C ++ / CLI,F#和许多其他程序。当然,所有其他转换也都可以。取得一个F#文件,编译为DLL,使用Reflector将其转换为C#。
当然,您会发现两个大问题:
#2确实没有什么可以解决的,但是您可以通过MSIL中的一些附加注释(可能通过属性)解决#1的问题。当然,那将是额外的工作。
Microsoft.NET\Framework\v2.0.50727\en
例如,如果您查看,则可以看到系统库的所有XML文档。这就是Reflector(等)用于显示评论的内容。转换不是不可读的,我只是说它不是源代码级翻译所期望的100%保真度。
至少在理论上,是否有可能在所有语言之间编写100%正确的翻译器?实践中有哪些挑战?
您为什么要转换程序?
无论哪种语言,无论是源语言还是目标语言,都将被编译为(虚拟)机器代码*,因此出于技术原因,无需使用另一种高级语言的编译器。
语言是人类的语言。因此,您问题的隐含要求是:“为什么没有生成可读代码的翻译器”,答案将是(imho):因为如果有两种语言完全不同,则编写“可读代码”的方式不同之处在于它不仅需要翻译算法,而且需要采用不同的算法。
例如,比较一个典型的C迭代和一个Lisp的迭代。或python与惯用红宝石的“一种最佳方式”。
在这里,用真实的语言开始出现同样的问题,例如将英语翻译为德语时,将“正在下雨的猫和狗”翻译成意思是“就像从水桶里倾泻的东西”,不再逐字翻译,但是您必须寻找含义。
而且“含义”并不是一个容易理解的概念。
*)好吧,有咖啡稿...
虽然它本身不是代码翻译,但语言工作台的概念显示了如何实现类似于所有语言之间100%正确的翻译器的功能。
在我们当前的方法中,源代码以文本格式存储。在编译期间,这些人类可读的文本文件被解析为抽象语法树表示形式,该语法树表示形式又用于生成字节码或机器代码。但是,此抽象表示是临时的,对于编译器而言是内部的。
在语言工作台方法中,类似的抽象语法树表示形式是永久性存储的工件。机器代码和文本“源”代码都是基于此抽象表示而生成的。这种方法的后果之一是程序的抽象表示实际上与语言无关,并且可以用来生成任何已实现语言的文本代码。这意味着一个人可以使用他们认为最合适的任何一种语言自由地在系统的不同方面进行工作,或者团队的每个成员都可以使用他们最熟悉的语言来从事共享项目。
据我所知,该技术仍无法在主流开发中使用,但是有数个小组在独立研究该技术。很难说他们中的任何一个是否能兑现诺言,但是看到这种情况会很有趣。
这里有一些自动翻译。如果您的目标是生成可编译的代码,而不是可读的代码,则很有可能并且偶尔有用,只是很少使用。著名的是,第一个C ++编译器实际上不是编译器,而是将C ++转换为(确实很复杂的)C源代码,然后由C编译器进行编译。许多编译器可以根据要求生成汇编代码-但是,除了吐出汇编文本然后将其翻译为机器代码外,它们通常可以直接生成机器代码。
给定语言A的完整规范,原则上编写用某种语言B表示其指令的程序并不难。但是通常,遇到麻烦的人都会为“语言B”选择非常低级的东西:机器代码或最近的字节码:Jython是python的一种实现,它生成Java字节码,由Java VM解释。无需费心编写和编译Java类层次结构!
这一直都在做。
每个编译器都会将 “基本语言”(如C ++)转换为机器的本机汇编语言或使用解释型语言的与体系结构无关的字节码。
我想那不是你在说什么。您可能需要一个将C ++转换为Java或Python之类的转换器。那有什么意义呢?充其量,最终结果将具有与原始来源完全相同的效率。(实际上,情况会更糟。)
如果您只想翻译代码,以便以您理解的语言来阅读代码,那么这样的翻译器将具有与预期效果相反的效果。您将获得大量的含糊不清,不直观和不可读的代码。
这是因为只有最琐碎的事物才能直接从一种语言翻译成另一种语言。通常,一种语言的简单性需要另一种语言的大量库-或完全不可能。因此:
最后,编写好的代码的唯一方法是实际编写代码。 在可读性,最佳实践和优雅的解决方案方面,计算机根本无法(至少目前还不能)与人类匹敌。
简而言之,这是不值得的。
没有编程语言的语言翻译器,因为编程语言非常复杂。尽管这是可能的,但仍然存在许多挑战。
第一个挑战仅仅是在可接受的语言实践中。在两种面向对象的语言(如Java和C ++)之间进行转换非常复杂,而且它们都是基于C的。翻译器程序必须对两种语言的标准库都有全面的了解,并且必须了解行为上的差异。您将不得不创建一个庞大的字典,即使那样,程序员之间的编程风格也将有所不同,这意味着它将不得不猜测如何执行某些更改。
掌握语法翻译后,就必须弄清楚如何将第一种语言的结构转换为第二种语言的结构。如果要将C ++中的对象转换为Java中的对象(相对来说比较容易),这很好,但是您如何处理C ++结构呢?还是C ++类之外的函数?决定如何处理它可能很棘手,因为它可能导致另一个问题,即创建Blob对象。斑点是很常见的反模式。
这不是问题的完整列表,但只是两个而已,它们很大。我的一位教授提到,有人说服了他的老板,他们可以在80年代从机器代码制作到C语言,但是那时不起作用。我怀疑会不会有一个完全有效的方法。