我可以对代码强制执行哪些模式,以便更容易翻译成另一种编程语言?

Nul*_*ion 95 php python compiler-construction coding-style abstract-syntax-tree

我打算做一个侧面项目,其目标是将代码从一种编程语言转换为另一种编程语言.我开始使用的语言是PHP和Python(Python到PHP应该更容易开始),但理想情况下我可以添加其他语言(相对)轻松.计划是:

  • 这是面向Web开发的.原始代码和目标代码将位于框架之上(我也必须编写).这些框架将采用MVC设计模式并遵循严格的编码约定.这应该使翻译更容易一些.

  • 我也在研究IOC和依赖注入,因为它们可能使翻译过程更容易,更不容易出错.

  • 我将使用Python的解析器模块,它让我摆弄抽象语法树.显然,我可以用PHP获得的最接近的是token_get_all(),这是一个开始.

  • 从那时起,我可以构建AST,符号表和控制流程.

然后我相信我可以开始输出代码了.我不需要完美的翻译.我仍然需要检查生成的代码并修复问题.理想情况下,翻译人员应标记有问题的翻译.

在你问"这到底是什么意思?"之前 答案是......这将是一次有趣的学习经历.如果您对如何减少这种麻烦有任何见解,请告诉我.


编辑:

我更感兴趣的是知道我可以在代码上强制执行哪种模式,以便更容易翻译(即:IoC,SOA?)代码而不是如何进行翻译.

Ira*_*ter 119

自1995年以来,我一直在构建工具(DMS软件再造工具包)以进行通用程序操作(语言翻译是一种特殊情况),由强大的计算机科学家团队提供支持.DMS提供通用解析,AST构建,符号表,控制和数据流分析,转换规则的应用,带有注释的源文本的再生等,所有这些都通过计算机语言的显式定义来参数化.

机器你需要做到这一点的量为广大的(特别是如果你希望能够在一个通用的方式来做到这一点对于多国语言),然后你需要用不可靠的定义语言可靠分析器(PHP是这个完美的例子).

你在考虑建立一个语言到语言的翻译或尝试它是没有错的,但我认为你会发现这对于真正的语言而言比你期望的要大得多.我们在DMS中投入了大约100个人年,在每个"可靠"语言定义中包含了6-12个月(包括我们为PHP设计的那个),更多的是针对像C++这样令人讨厌的语言.这将是一个"学习经历的地狱"; 它一直适合我们.(您可能会发现上述网站上的技术论文部分很有趣,可以开始学习).

人们经常尝试通过他们熟悉的某种技术开始构建某种通用机器,这是一项工作的一部分.(Python AST是很好的例子).好消息是,部分工作已经完成.坏消息是,机器内置了许多假设,其中大部分都是在你试图将其用于其他事情之前不会发现的.在那一点上,你发现机器是有线的做它原来做的,并且真的,真的,抵制你尝试做它做其他事情.(我怀疑试图让Python AST模型化PHP会很有趣).

我最初开始构建DMS的原因是为了构建内置很少这样的假设的基础.它有一些令我们头疼的事情.到目前为止,没有黑洞.(过去15年来,我工作中最难的部分就是试图防止这种假设蔓延开来).

许多人也错误地认为,如果他们可以解析(并且可能获得AST),那么他们就可以做出复杂的事情了.其中一个难点是需要符号表和流量分析才能进行良好的程序分析或转换.AST是必要的,但还不够.这就是Aho&Ullman的编译器书在第2章没有停止的原因.(OP有这个权利,因为他计划建立超出AST的额外机制).有关此主题的更多信息,请参阅解析后的生活.

关于"我不需要完美翻译"的评论很麻烦.弱译者所做的是转换80%的"简单"代码,让20%的代码手工完成.如果您打算转换的应用程序非常小,并且您只打算将其转换一次,那么20%就可以了.如果你想转换许多应用程序(或者甚至是随着时间的推移而发生微小变化的同一个应用程序),这并不好.如果您尝试转换100K SLOC,则20%是20,000条原始代码行,难以翻译,理解和修改您已经不理解的另外80,000行翻译程序.这需要付出巨大的努力.在百万行级别,这在实践中根本不可能.更难,他们通常会痛苦地发现长时间的延误,高成本和经常彻底的失败.)

您需要为翻译大型系统而拍摄的内容是九十年代的百分比转换率,或者您可能无法完成翻译活动的手动部分.

另一个关键考虑因素是要翻译的代码大小.即使使用好的工具,构建一个可靠,强大的翻译器也需要很多精力.虽然构建翻译器而不是简单地进行手动转换似乎性感和酷,但对于小代码库(例如,在我们的经验中高达约100K SLOC),经济学根本就没有理由.没有人喜欢这个答案,但是如果你真的需要翻译10K SLOC的代码,你可能最好只是咬紧牙关并做到这一点.是的,这很痛苦.

我认为我们的工具非常好(但是,我很偏颇).建立一个好的翻译仍然很难; 它需要我们大约1.5-2人年,我们知道如何使用我们的工具.不同之处在于,通过这么多机器,我们比失败更成功.

  • 我被要求让许多我们做的事情"开源",许多人不想为收入流做出贡献,并且没有精力去做这项工作并自己开源.如果你只为一个非常大的项目贡献一小部分,和/或你有另一个收入来源,"开源"似乎很好.如果你自己完成了所有的工作并且是你唯一的收入来源,那么这就不那么有吸引力了.[我不想讨论"自由软件"哲学的相对优点,所以我不会参与此行的任何进一步评论] (52认同)
  • 我同意你在这里说的话,这就是为什么我像我一样提出这个问题.我想我们应该直截了当地回答你认为它与你的收入关系太紧密了,而且这绝对没有错 - 我只是觉得值得问. (9认同)
  • 您有没有考虑过将"痛苦建立"的PHP定义贡献给整个PHP社区,或者是否与您自己的收入流密切相关以使其可行? (8认同)
  • @IraBaxter你只是说与计算机有关的实践的常用习语可以应用于很多其他的实践.您写的所有内容中唯一的内容是指向semanticdesigns.com的链接(恰好是您的公司) (3认同)
  • 您经常在答案中提供指向 Clang 相关页面的链接。那只能证明其他人可以制作网页。我们大多数人都认为,一个写得好的网页意味着背后有认真的、真实的工作,而不仅仅是你在回答中似乎暗示的一些欺骗读者的企图。您真的相信该网页是欺诈性的吗?该页面包含“相关”来源的参考信息;它是匿名的,因为工作合同要求这样做。我无能为力。 (2认同)

Eli*_*sky 13

我的答案将解决解析Python的具体任务,以便将其翻译成另一种语言,而不是Ira在他的答案中解决的高级方面.

简而言之:不要使用解析器模块,这是一种更简单的方法.

ast从Python 2.6开始提供的模块更适合您的需求,因为它为您提供了现成的AST.我已经写了一本关于文章最后一年,但在短,使用parse的方法ast来分析Python源代码到AST.该parser模块将为您提供一个解析树,而不是AST.警惕差异.

现在,由于Python的AST非常详细,给定AST前端工作并不十分困难.我想你可以很快就拥有一个简单的原型来完成功能的某些部分.但是,获得完整的解决方案需要更多时间,主要是因为语言的语义不同.语言的一个简单子集(函数,基本类型等)可以很容易地被翻译,但是一旦你进入更复杂的层,你将需要繁重的机器来模拟另一个语言的核心.例如,考虑PHP中不存在的Python生成器和列表推导(据我所知,当涉及到PHP时,这一点肯定很差).

为了给您最后一个提示,请考虑2to3Python开发人员创建的工具将Python 2代码转换为Python 3代码.前端方面,它具有将Python翻译成某些东西所需的大部分元素.但是,由于Python 2和3的核心相似,因此不需要仿真机制.

  • @Aaron:`2to3`可以看作是使用`ast`生成的AST的一个例子. (2认同)

Way*_*ner 5

写一个翻译并非不可能,尤其是考虑到乔尔的实习生在一个夏天做到了.

如果你想做一种语言,这很容易.如果你想做更多,这有点困难,但不是太多.最难的部分是,虽然任何图灵完整语言都可以完成另一种图灵完整语言所做的事情,但内置数据类型可以改变语言的现象.

例如:

word = 'This is not a word'
print word[::-2]
Run Code Online (Sandbox Code Playgroud)

需要大量的C++代码才能复制(好吧,你可以用一些循环结构做到相当简短,但仍然如此).

我猜,这有点偏僻.

你有没有根据语言语法编写一个标记器/解析器?如果你没有,你可能想学习如何做到这一点,因为这是这个项目的主要部分.我要做的是提出一个基本的图灵完整语法 - 与Python 字节码非常相似 .然后,您创建一个带有语言语法(可能使用BNF)的词法分析器/解析器,并根据语法将语言编译为您的中间语言.那么你要做的就是反过来 - 根据语法从你的语言创建一个解析器到目标语言.

我看到的最明显的问题是,起初你可能会创建非常低效的代码,尤其是在像Python这样更强大的*语言中.

但是如果你这样做,那么你可能会找到优化输出的方法.总结一下:

  • 阅读提供的语法
  • 将程序编译成中间(但也是图灵完成)语法
  • 将中间程序编译成最终语言(基于提供的语法)
  • ...?
  • 利润!(?)

*强大我的意思是这需要4行:

myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]
Run Code Online (Sandbox Code Playgroud)

向我展示另外一种可以用4行代码完成的语言,我将向您展示一种与Python一样强大的语言.

  • 乔尔的实习生在一个夏天做了一份部分工作.他的源语言是现有语言的一个子集,可能这个子集可以稍微调整一下.这使得工作变得更加容易.类似地,NullPointerException可能希望从Python的更简单部分开始,也许可以通过更难的手动转换(如问题中所述). (2认同)