来自斯坦福大学的编译原理课程,课程已收录到edx,b站有部分中文翻译的视频
课程地址
课程目录
01-01 Introduction 实现编程语言的两种方式:Compilers(编译器)和Interpreters(解释器)
解释器和编译器的区别:
在解释器执行程序前,不需要对这个程序做任何处理,解释器是整个程序运行的一部分
编译器的功能:编译是生成机器码的预处理过程
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汇编
得到:
运行成功
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手册