使用LLVM开发新语言Kaleidoscope教程

  |   2 评论   |   664 浏览

原文链接: 使用LLVM开发新语言Kaleidoscope教程

前言: 本系列是 My First Language Frontend with LLVM Tutorial 译文,诣在熟悉LLVM的开发流程,网上有一些翻译只有前三个部分,没有翻译全,并且都是四五年前的没有更新过。由于对于编译器的概念只停留在理论上,想从代码的角度深入理解一下编译器,希望通过这部分的练习可以帮助到我。利用国庆假期这几天,我会仔细阅读此系列文档及源码并尝试翻译和记录。

要求: 本教程只需要了解C++语言知识,编译器的相关经验不是必需的。

本教程介绍了一种简单语言的实现,展示了它多么有趣和轻松。本文将帮助我们快速入门,运行并演示使用LLVM生成代码的具体示例。

本教程将开发一个简单的“Kaleidoscope”语言,并在连续几章中对其进行迭代构建,并展示如何逐步构建。这样一来,我们就可以涵盖一系列语言设计和LLVM特定思想,一路展示和解释其代码,并减少大量的细节分析。我们强烈建议动手复制修改并运行代码,以此加深对编译器实现的理解。

友情提示: 为了专注于专门讲授编译器技术和LLVM,本教程没有展示软件工程原理的最佳实践。例如,代码普遍使用全局变量,不使用visiters设计模式等,而是使事情保持简单并专注于手头的编译器实现。

本教程分为以下十章,涵盖各个主题,你可以随意跳过从感兴趣的地方开始看:

  • 第一章:Kaleidoscope语言和Lexer 这部分展示了我们要做的基本功能。词法分析器也是构建语言解析器的第一部分,我们使用了易于理解的简单 C++词法分析器。
  • 第二章:实现解析器和AST 有了词法分析器,我们可以讨论解析技术和基本AST构造。本章介绍了递归下降解析和运算符优先级解析。
  • 第三章: 生成LLVM中间代码IR 在准备好AST之后,我们将展示LLVM生成IR的简便性,并展示了一种将LLVM集成到项目中的简单方法。
  • 第四章: 添加JIT和Optimizer支持 LLVM的一大优点是它对JIT编译的支持,因此我们将深入探讨它,并展示添加JIT支持所需的三行内容。后面的章节介绍了如何生成.o文件。
  • 第五章: 扩展语言---控制流 随着基本语言的启动和运行,我们展示了如何通过控制流操作(“ if”语句和“ for”循环)进行扩展。这使我们有机会讨论SSA的构建和控制流程。
  • 第六章: 扩展语言---用户定义运算符 本章扩展了语言,使用户可以定义任意一元和二进制运算符并具有相应的优先级。这使我们可以将很大一部分“语言”构建为库例程。
  • 第七章: 扩展语言---可变变量 本章节讨论如何用赋值语句添加用户自定义地本地变量。有趣的是,构造SSA在LLVM是相当简单的,但是LLVM并不要求你的前端来构造SSA结构。
  • 第八章: 编译为目标代码 本章介绍如何获取LLVM IR并将其编译为目标代码,就像静态编译器一样。
  • 第九章: 增加调试信息 一种真正的语言需要支持调试器,因此我们添加了调试信息,该信息允许在Kaleidoscope函数中设置断点,输出参数变量和调用函数!
  • 第十章: 总结和其他技巧 本章通过讨论扩展语言的方式来总结本系列,并包括指向“special topics”的信息的指针,例如添加垃圾收集支持、异常处理、调试和对“spaghetti stacks”的支持等。

在本教程结束时,我们将编写不超过1000行(除去注释和空行)代码。借助少量的代码,我们将为一个普通的语言构建一个功能齐全的小型编译器,其中包括手写词法分析器,解析器,AST,以及代码生成(包括静态编译和JIT编译)。这种扩展充分证明了LLVM的优势,并说明了为什么LLVM被众多语言设计人员和其他研究高性能代码生成的人所喜爱。


参考:My First Language Frontend with LLVM Tutorial

评论

发表评论