Szafraniec, M. et al. Code Translation with Compiler Representations. Preprint at http://arxiv.org/abs/2207.03578 (2023).
1 引言
- 自动代码翻译可以将旧代码库迁移到新框架,或将高级语言转换为低级语言。
- 传统代码翻译方法(transpilers)依赖语法信息和手工规则,存在局限性,生成的代码不自然且难以阅读。
- 神经机器翻译(NMT)方法在生成自然代码方面取得了进展,但无法有效区分具有不同语义的相似代码片段,导致翻译质量低。
- 本文提出利用编译器中间表示(IR)来改进代码翻译,特别是使用 LLVM IR,以提高翻译的准确性和语义质量。
2 编译器中的中间表示
- 编译器将源代码转换为可执行代码,包括前端、中间端和后端。
- 前端进行词法分析、语法分析和语义分析,生成抽象语法树(AST)。
- 中间端将 AST 转换为中间表示(IR),例如 LLVM IR,它是一种语言无关的伪代码,描述了程序的语义。
- 后端将 IR 转换为目标架构的机器代码。
3 训练目标
- 机器翻译的训练目标包括学习多语言序列嵌入和生成目标语言的序列。
- TransCoder 使用三种目标函数进行训练:掩码语言模型(MLM)、去噪自动编码(AE)和回译(BT)。
- 本文提出了三种新的目标函数,利用 LLVM IR 改进代码表示:
- 翻译语言模型(TLM):学习源代码和 IR 之间的对应关系。
- 翻译自动编码(TAE):学习从噪声源代码和 IR 中恢复原始代码。
- IR 生成(MT):学习将源代码翻译成对应的 IR。
- IR 逆向工程和 IR 中继翻译是两种替代方法,但本文提出的方法在性能上更优。
4 数据
- 训练数据来自 Google BigQuery 和 CodeNet 数据集,包含 C++、Go、Java 和 Rust 语言的函数。
- 使用 Clang++、JLang、Gollvm 和 rustc 生成 LLVM IR,并进行预处理,例如去除无关信息和优化代码。
- 训练数据包括单语数据和多语言平行数据。
5 结果
- 实验使用了 TransCoder 作为基线模型,并介绍了模型架构和训练过程。
- 使用 TLM、TAE 和 MT 目标函数可以将平均翻译准确率提高 11%,在低资源语言对上的提升更为显著。
- IR 逆向工程模型的准确率达到 77.9%,优于基于规则的逆向工程工具。
6 讨论
- 不同 IR 和解释型语言:IR 作为中继的适用性取决于源语言和目标语言是否共享相同的 IR。
- 中继与嵌入:TransCoder 使用源代码进行翻译,而中继方法使用 IR 进行翻译。本文提出的方法结合了两种方法的优点,可以学习多语言代码表示并提高翻译质量。
- 使用模型进行推理:模型在推理时不需要计算 IR,可以直接从源代码生成翻译。
7 相关工作
- 介绍了源到源翻译、神经机器翻译和逆向工程方面的相关工作,例如 TransCoder、DOBF、C2Rust、CxGo、RetDec 等。
8 结论
- 本文利用 LLVM IR 改进了代码翻译的准确性和语义质量。
- IR 增强代码表示方法具有广泛的应用前景,可以应用于任何共享相同 IR 的语言对。
- 未来工作可以探索更大规模的 IR 数据集和更复杂的模型,例如生成 IR 的编码器和解码器。