来自斯坦福大学的编译原理课程,课程已收录到edx,b站有部分中文翻译的视频

课程地址

课程目录

01-01 Introduction

实现编程语言的两种方式:Compilers(编译器)和Interpreters(解释器)

解释器和编译器的区别:

  • 在解释器执行程序前,不需要对这个程序做任何处理,解释器是整个程序运行的一部分
  • 编译器的功能:编译是生成机器码的预处理过程

image.png

01-02 Compilers

编译器的结构:

  • Lexical Analysis(词法分析)
  • Parsing(语法分析)
  • Semantic Analysis(语义分析)
  • Optimization(优化)
  • Code Generation(代码生成)
  • 词法分析的目标就是将程序代码文本按照它的方式进行分词,就是编译器说话时对词的区分

02-01 COOL Overview

本次学习将以COOL语言为例,实现COOL语言的编译器,将其翻译成mips汇编语言

由于COOL语言被大量用于编译器教学,因此其可能也是少有的编译器数量多于COOL程序数量的语言

首先需要配环境:

1
2
wget https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@student-dist.tar.gz
tar -xf student-dist.tar.gz

bin目录下有需要的coolc和spim,coolc用于编译cool代码,spim用于执行mips汇编

这里写个cool示例1.cl:

1
2
3
4
5
class Main{
main() : Int {
1
};
};

main函数仅做返回1的操作

通过执行coolc 1.cl生成1.s

通过spim 1.s执行mips汇编

得到:

image.png

运行成功

helloworld.cl示例:

1
2
3
4
5
6
class Main{
i : IO <- new IO;
main() : Object {
i.out_string("Hello World!\n")
};
};

02-02 COOL Example II

后面主要是根据一些示例,学习COOL的基本用法

打印用户输入:

1
2
3
4
5
class Main{
main() : Object {
(new IO).out_string((new IO).in_string().concat("\n\n"))
};
};

将用户输入的数字+1后输出:

1
2
3
4
5
class Main inherits A2I {
main() : Object {
(new IO).out_string(i2a(a2i((new IO).in_string())+1).concat("\n\n"))
};
};

lib目录下有A2I类的定义,需要将此文件与atoi.cl一起编译:coolc 1.cl atoi.cl

实现计算阶乘(循环,局部变量使用等):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Main inherits A2I {
main() : Object {
(new IO).out_string(i2a(fact(a2i((new IO).in_string()))).concat("\n\n"))
};

fact(i: Int): Int{
let fact: Int <- 1 in {
while (not (i = 0)) loop
{
fact <- fact * i;
i <- i -1;
}
pool;
fact;
}
};
};

02-03 COOL Example III

定义多个变量来输出Hello World:

1
2
3
4
5
6
7
8
9
class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
newline: String <- "\n"
in
out_string(hello.concat(world.concat(newline)))
};
};

自写一个List类来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class List {
item: String;
next: List;

init(i: String, n: List): List{
{
item <- i;
next <- n;
self;
}
};

flatten(): String{
if (isvoid next) then
item
else
item.concat(next.flatten())
fi
};

};

class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
newline: String <- "\n",
nil: List,
list: List <- (new List).init(hello,
(new List).init(world,
(new List).init(newline, nil)))
in
out_string(list.flatten())
};
};

添加case结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class List inherits A2I{
item: Object;
next: List;

init(i: Object, n: List): List{
{
item <- i;
next <- n;
self;
}
};

flatten(): String{
let string: String <-
case item of
i: Int => i2a(i);
s: String => s;
o: Object => { abort(); ""; };
esac
in
if (isvoid next) then
string
else
string.concat(next.flatten())
fi
};

};


class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
i: Int <- 42,
newline: String <- "\n",
nil: List,
list: List <- (new List).init(hello,
(new List).init(world,
(new List).init(42,
(new List).init(newline, nil))))
in
out_string(list.flatten())
};
};

COOL语言的学习就暂时到这里,更多关于COOL的语法可以看COOL的手册:

COOL手册