2

非 CS, 想弄弄编译, 还啃龙书吗?

 1 year ago
source link: https://www.v2ex.com/t/883710
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

非 CS, 想弄弄编译, 还啃龙书吗?

  andyJado · AndyJado · 10 小时 24 分钟前 · 2530 次点击
29 条回复    2022-09-29 19:17:39 +08:00
xtreme1

xtreme1      10 小时 16 分钟前   ❤️ 1

你是要搞哪一块..
如果只是想快速了解一下, 可以找一些 LLVM 教程看一看
Lax

Lax      10 小时 8 分钟前

书店随便买一套普通教材看看吧
离散数学-形式语言与自动机-编译原理
Mithril

Mithril      10 小时 5 分钟前   ❤️ 1

不建议直接啃。
如果你会写代码的话,可以找找教程用你熟悉的语言实现个简单的编译器。弄个 JSON 解析器,或者做个简单的 DSL 等等。遇到哪里不懂的名词去查或者直接翻书就行。
这样你对于编译这个过程有个直观的理解以后,再去啃就会容易很多。
而且你也能知道自己想要学的那部分,对应的是哪些技术。学起来也更有目的性。
shijingshijing

shijingshijing      10 小时 3 分钟前   ❤️ 1

其实现在编译器开发也有划分了前端( Front End )与后端( Back End ),前端偏算法和数据结构;后端偏硬件底层和系统架构。看你准备弄哪一块?

而且搞编译器出来工作岗位也不多吧。。。 搞这个的都是大牛。
heyjei

heyjei      10 小时 1 分钟前   ❤️ 1

非专业人士,看看 Antlr 就足够了,而且还有一定的实用性
zsj950618

zsj950618      7 小时 38 分钟前 via Android

龙书只是入门吧。。。你要是连一些名词都不知道,其他直接上手的教程估计看不懂。。。
zsj950618

zsj950618      7 小时 36 分钟前 via Android

或者说看龙书的时候,一些算法没看懂可以不着急研究,但书总归要先翻一遍
SmiteChow

SmiteChow      7 小时 32 分钟前

编译原理是基础,跳不过的,概念要清楚,要不然你可能连最基本的文法一关都过不去。
billlee

billlee      7 小时 20 分钟前 via Android   ❤️ 1

快速上手建议看 antlr 手册,跑起来以后要加高级特性的时候再看龙书
DianQK

DianQK      6 小时 28 分钟前   ❤️ 4

我当前学习的路线供参考


- Computer Systems: A Programmer's Perspective
- Crafting Interpreters (替代 自己动手实现 Lua 虚拟机、编译器和标准库)
- 程序员的自我修养:链接、装载与库(替代 上面的 CSAPP )


- 清华大学的《数据结构( C++ 语言版)》邓俊辉(看了一部分,很棒!)学习中


- **南京大学 软件分析 [**https://tai-e.pascal-lab.net/**]( https://tai-e.pascal-lab.net/) 国内顶级的静态分析课程,最近看完了所有的视频,也完成了 OJ 作业,非常棒的课程**
- Compilers: Principles, Techniques, and Tools (以下几章可以算是上面的软件分析的下一步学习的扩展)
- 6.2 Three-Address Code
- 8 Code Generation
- 9 Machine-Independent Optimizations
- 12 Interprocedural Analysis (还没开始看)计划待看
- CS 6120: Advanced Compilers γ https://www.cs.cornell.edu/courses/cs6120/2020fa/ 看了一半搁置了


- **LLVM Techniques, Tips, and Best Practices Clang and Middle-End Libraries 上手 LLVM 前一定要看**
- https://github.com/banach-space/llvm-tutor ​学习中
- Learn LLVM 12: A Beginner's Guide to Learning LLVM Compiler Tools and Core Libraries With C++

其他参考
- [编译高级教程|学习笔记]( https://leiblog.wang/%E7%BC%96%E8%AF%91%E9%AB%98%E7%BA%A7%E6%95%99%E7%A8%8B%EF%BD%9C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/)
- [2019 EuroLLVM Developers’ Meeting: V. Bridgers & F. Piovezan “LLVM IR Tutorial - Phis, GEPs ...”]( )
- [Creating the Bolt Complier 系列]( https://mukulrathi.com/create-your-own-programming-language/intro-to-compiler/)
Ta0Ta0Ta0

Ta0Ta0Ta0      6 小时 8 分钟前   ❤️ 1

我推荐一下哈工大姜守旭老师的编译原理视频课程吧,思路清晰,这门课靠他的讲述拿了个不错的分
andyJado

andyJado      5 小时 19 分钟前

@DianQK
我目前的进展:

wow, bit and context, 我悟了.

@gengjiawen

https://book.douban.com/review/13617730/

已标记, 但, 也许我心中真正好奇的是, 编译是他妈的在干嘛, 为啥要整那些呢? AST 放松了什么痛苦? MIR 呢?
littlewing

littlewing      5 小时 17 分钟前   ❤️ 1

直接搞 llvm
hk3475

hk3475      5 小时 8 分钟前   ❤️ 1

看 crafting interpreter 就够了 还有龙书太重 parse 了 你不搞学术的话 搞懂 recursive decent 就行了 后面可能也是用 antlr 之类的多
Origami404

Origami404      4 小时 44 分钟前 via Android   ❤️ 1

我的理解是编译即翻译,是数据结构跟特性的变化。

数据结构的变化的话主要有:文本->词法流,词法流->ast ,文本->ast ,ast->各种类型的 ir 。

特性的变化主要是有无变量,有无语句还是纯表达式,有无非局部控制流,有无闭包,有无宏,有无可直接访问的线性内存,有无模板之类的。

要学哪一步就要学特定的实现方法,比如词法流->ast 就有一堆 ll ,lr ,parser combinator 之类的。然后各个特性的翻译也是有要学的
Origami404

Origami404      4 小时 40 分钟前 via Android   ❤️ 1

实践上我觉得最难的是从有变量的语言转到无变量的语言 /ir 的实现,这意味着将表述程序的重心从内存位置转移到值,需要做很多分析。
Origami404

Origami404      4 小时 38 分钟前 via Android   ❤️ 1

当然要实现特定的大的特性,比如基于原型的 oop ,类似 Java 那样的 oop ,惰性运算,条件系统那种的话,还要再深入具体体系看看设计。
Origami404

Origami404      4 小时 35 分钟前 via Android   ❤️ 1

做多趟编译器的话感觉首先是要想好 ir 形式,是指令变量分离的三地址,还是类似 llvm 跟 graal 的图状 ir ,又或者是 lisp 系的 cps 。很多时候理解了 ir 跟源语言之后从 ast 到 ir 这一步就都迎刃而解了
Origami404

Origami404      4 小时 25 分钟前 via Android   ❤️ 1

@andyJado AST 是程序结构的抽象表示,使用 ast 可以完全将语义部分(即遇到什么程序结构要干什么)跟解析部分(从词法流中解析出程序结构)分离开来。在早期不分的情况下,必须在解析部分就指定解析出的程序结构的语义,就会导致代码耦合。

其实换一种角度想,你可以将 AST 视作一种“所有语言都具有的语义”,因为它表达且只表达了程序结构,没有任何多余信息。

其实可以各种各样的 IR 就是各种各样的数据结构。我们使用数据结构的目的就是为了方便插入 /提取某些信息,方便一些算法的使用。使用某种 IR 的目的也是这样,不同种类的 IR 能方便地获取源程序中不同的信息,从而方便不同的优化算法使用。

当然了,IR 本身作为一个 AST 跟实际汇编语言后端之间的抽象层这个作用也是很重要的,它能极大方便多后端编译器的开发。
nightwitch

nightwitch      4 小时 7 分钟前   ❤️ 1

parser 只掌握递归下降 LL1 可以解决 90%的问题了。
重点在后端求值和优化部分,从字符串到 ast 都是体力活,换着花样解析没太大意义。
dog82

dog82      3 小时 56 分钟前

炸出一堆大神,我编译原理只肝到语法分析,我天资差感觉太难了
bruce0

bruce0      2 小时 18 分钟前

@dog82 我都没去肝过, 我自认为不是那块料🐶
penguinWWY

penguinWWY      1 小时 33 分钟前

啃龙书没啥意义。
如果你想整体了解编译,不要在 parser 上浪费时间,parser 是一个非常“符合直觉”的事情,本质上就是如何把一段文本变成结构化的数据,所以不要被各种名词唬住,自己写一个简单的表达式解析器,就能大概明白了。同时 parser 在整个编译过程中只占了很小的一部分,基本没啥值得关注的东西。

编译整体看是一个不断 lower ( desuger )的过程,用简单代替复杂,具体代替抽象。所以整体看的话,你需要大概了解一下体系结构和指令集,也就是编译的终点是什么样的。中间的过程不管是 AST 也好,IR 也好,no-target machine code 还是 target machine code ,从认知上来讲,都不是必须的(你完全可以设计一个非常简单的表达式语言,然后直接翻译成汇编指令),这些步骤只是为了满足某种需求( native code or Interpreter ? JIT or AOT ? interprocedural or intraprocedural ?)而增加的、便于使用的中间层。

明确输入(语言、特性、功能)和输出(目标指令集),剩下的就是取舍和拼接。现在编译体系复杂之处在于为了某些目标(性能、功能、复杂的语言特性)而在不同层次间不得不产生耦合,使用某些约定(而不是设计)。当这种情况越多,原本清晰的结构就会变成一坨。。。
andyJado

andyJado      1 小时 15 分钟前

> 这意味着将表述程序的重心从内存位置转移到值

@Origami404 谢谢老师! 我也去体会体会🏃
andyJado

andyJado      1 小时 4 分钟前

@penguinWWY 挠到了! 谢谢老师!
woctordho

woctordho      28 分钟前

建议边做边学,你可以先试试发明一门新的语言,比如用东北话编程 https://github.com/zhanyong-wan/dongbei

先用土办法写一个解释器,然后再看编译原理里的那些概念,就知道你自己在干什么了

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK