PKU 编译原理实践 - CS自学指南 北京大学编译实践课程在线文档

前置知识:

  1. linux 命令
  2. git 命令
  3. gdb 调试命令
  4. makefile 写法
  5. docker

环境准备

首先 docker 拉镜像

docker pull maxxing/compiler-dev

运行镜像

设置卷映射 /mnt/d/Code/rust/sysy-compiler:/root/compiler

docker run -it -v /mnt/d/Code/rust/sysy-compiler:/root/compiler

拉去项目模板

以 rust 语言为例

git clone https://github.com/pku-minic/sysy-cargo-template.git

使用 vscode 编辑代码

编译 main 函数和 return 语句

实现编译

int main() {
  // 注释也应该被删掉哦
  return 0;
}

生成 koopa IR

fun @main(): i32 {
%entry:
  ret 0
}

编译器工作过程

词法分析语法分析语义分析IR生成目标代码(汇编)生成

字符串 单词流

语义分析:建立符号表,类型检查,编译期计算

词法分析规范(采用扩展巴科斯范式 EBNF)

概念:产生式,推导,终结符,非终结符

标识符(identifier)

identifier ::= identifier-nondigit
             | identifier identifier-nondigit
             | identifier digit;
identifier-nodigit ::= [a-zA-Z_]
digit              ::= [0-9]

数值常量

区分十进制、八进制、十六进制

integer_const       ::= decimal_const
                      | octal_const
                      | hexadecimal_const;
decimal_const       ::= nonzero_digit
                      | decimal_const digit;
octal_const         ::= "0"
                      | octal_const octal_digit;
hexadecimal_const   ::= hexadecimal_prefix hexadecimal_digit
                      | hexadecimal_const hexadecimal_digit;
hexadecimal_prefix  ::= "0x" | "0X";

语法分析

CompUnit  ::= FuncDef;
 
FuncDef   ::= FuncType IDENT "(" ")" Block;
FuncType  ::= "int";
 
Block     ::= "{" Stmt "}";
Stmt      ::= "return" Number ";";
Number    ::= INT_CONST;

使用 msys2 配置 c++ 环境

编写 sysy.l sysy.y main.cpp 三个文件,在 docker 环境下运行