是否存在可以在任何两种语言之间“翻译”源代码的程序(假设翻译者可以访问必需的库)?
如果存在,它们如何工作(使用的技术,所需的知识等)?它们将如何可行地构造?
如果不是,阻碍其发展的限制因素是什么?这是AI的完整问题(自然语言翻译列为其中一个)吗?
仅当语言具有相同的表达能力时,才可以预期 EDIT转换,可以解决相同类型的问题,并且要转换的代码可以用目标语言表示。(例如,不建议将Shell脚本转换为MATLAB)。
是否存在可以在任何两种语言之间“翻译”源代码的程序(假设翻译者可以访问必需的库)?
如果存在,它们如何工作(使用的技术,所需的知识等)?它们将如何可行地构造?
如果不是,阻碍其发展的限制因素是什么?这是AI的完整问题(自然语言翻译列为其中一个)吗?
仅当语言具有相同的表达能力时,才可以预期 EDIT转换,可以解决相同类型的问题,并且要转换的代码可以用目标语言表示。(例如,不建议将Shell脚本转换为MATLAB)。
Answers:
TLDR;这是可能的,但不切实际。
(假设翻译者可以访问必需的库)?
这最终是棘手的事情,也是为什么这样的事情最终没有在实践中使用的原因之一。
所有编译器都是翻译器。从一种语言到另一种语言的转换绝对是可能的,这实际上是编译器所做的全部工作。编译器作为输出输出的语言通常是机器代码或汇编语言,但这只是另一种语言,并且存在编译器(有时称为翻译器或编译器),它们在两种语言之间进行翻译。例如,有各种各样的可编译为Javascript语言,例如PureScript,Elm,ClojureScript等。
始终可以在任何两种Turing Complete语言之间进行翻译。就是忽略诸如库调用和FFI之类的东西以及其他讨厌的实用位。如果一种语言是图灵完备,那么您将:
因此,要从语言A转换为语言B,您需要将A代码转换为图灵机,然后将该机器转换为B代码。
当然,在实践中,实用的工具会妨碍您的工作,这也需要您可以使用翻译。它们几乎适用于每种语言,但这并不意味着有人花时间将它们写出来。
有效地执行此翻译非常困难。不同的语言会优先处理不同的事情。例如,如果您从C转换为Python,则可能最终不得不将C的内存模拟为Python字典,以便可以执行指针算术。与此相关的开销很大,因为您现在不访问裸机存储器指令。
不同的语言具有不同的性能优先级,因此用一种语言进行优化(或者用一种语言的实现进行优化)可能无法用另一种语言快速完成。如果将功能语言翻译为没有正确的尾部调用的功能语言,则会减慢其速度。
进行这种翻译不会使代码可读。用语言B获得的一段代码与语言A中的代码具有相同的功能是很容易的。由于多种原因,很难使它看起来像人类用B编写的代码。A和B可能具有不同的抽象工具,并且计算机不知道是什么使代码可读。如果您最终使用了我之前描述的Turing Machine转换,则尤其如此。
这就提出了一个问题:这样的翻译有什么意义?如果最后您得到的是一块缓慢的,无法读取的代码,为什么不将其编译为机器代码并使用某种FFI或进程间通信将各部分链接在一起呢?
这有一些例外。有时,您需要使用某种特定语言(例如JavaScript)的内容。有时语言是相似的,明智的翻译很容易。有时,一种语言不是要运行的,而是要将其代码提取到另一种语言(例如Coq)中。
但是总的来说,这不是一件很实际的事情。
有这样的程序。例如,Lisp到Fortran转换器在当时被广泛使用。唯一的Lisp编译器不会直接编译Lisp,而是生成C代码,然后由常规C编译器进行编译。另一个示例是Vala,它不会直接编译,而是在编译C ++代码之前首先转换为C ++。Qt用MOC编写,这是一种语言,可以翻译成C ++进行编译(但由于MOC只是C ++,还有一些其他命令,如果它真的要被命名为“新语言”,则可以争论)-在此之前是C ++编译器,还有C ++到C转换器。而且有些项目是用Pascal编写的,然后翻译为C。clang和Java也倾向于将C ++和Java代码翻译为某种中间语言,然后可以进一步处理。
您不会期望语言翻译器的输出是对人类读者有意义的结果:该程序的任务是编写代码,使程序与原始代码具有相同的功能(根据我的经验,这可能或可能无效,具体取决于语言的功能和所使用的外部库。但是由于它不知道目的是为了完成程序其余部分的意义,因此可能会在很大程度上丢失该任务。
这不是一个直接的答案,但是其中有一个工具调用ILSpy,它是为.Net Framework编写的,允许您将.Net程序集反编译为C#或VB.Net。
如果您不熟悉.Net的性质,则可以使用多种语言(主要是C#或VB.Net)编写.Net代码。当编译器编译应用程序时,它将代码转换为“中间语言”(或简称为IL)代码。然后将此代码编译为.Net二进制文件。
由于.Net应用程序是从IL代码编译的二进制文件,因此ILSpy可以使用.Net应用程序,将其反向转换为IL代码,然后再进一步将其反向执行,然后反向转换为C#或VB.Net。
使用此工具,您所需要做的就是编译应用程序,然后您可以将编译后的文件浏览为IL,C#或VB.Net代码。清楚地说,代码最初使用哪种语言都没有关系。只要二进制文件是.Net程序集,它就可以对工程文件进行反向工程并将其内容输出为这三种语言中的任何一种。
我知道这不是一个完全编译器,但是它提供的最终结果与您所寻找的类似,实际上,我已经使用它来将VB.Net项目“翻译”成一些东西我更熟悉-C#。
对于您的用例(基于评论),听起来SWIG可能有用。
SWIG是一种软件开发工具,可将用C和C ++编写的程序与各种高级编程语言相连接。SWIG与不同类型的目标语言一起使用,包括常见的脚本语言,例如Javascript,Perl,PHP,Python,Tcl和Ruby。支持的语言列表还包括非脚本语言,例如C#,Common Lisp(CLISP,Allegro CL,CFFI,UFFI),D,Go语言,Java(包括Android),Lua,Modula-3,OCAML,Octave,Scilab和R还支持几种解释和编译的Scheme实现(Guile,MzScheme / Racket,Chicken)。