2024-编译原理-IR篇
1. IR基础知识
“The effectiveness of a compiler depends heavily on the design of its
intermediate representation.”
— Keith D. Cooper, Linda Torczon, "Engineering a Compiler", 2nd
Edition, 2011.
编译系统的效果在很大程度上取决于
IR(Intermediate
Representation,中间表示)的设计。LLVM的成功很大程度上归功于其精良的LLVM
IR设计。
一个IR相当于编译架构中的一个抽象层次,一个好的IR为其所在层次上的代码分析、转换、优化提供了便利。
IR解耦了编译器前后端,为多前端、多后端的需求提供了统一的中间表示,下图说明了编译器架构的演化:
1.1 IR的分类
1.1.1 根据抽象层次
HIR (High-level Intermediate...
2024-编译原理-语法篇
1 语法分析的理论基础
1.1 上下文无关文法
上一讲中我们使用正则语言的泵引理(Pumping
Lemma)证明了
并非正则语言。还有一些常见的语言,如回文串 也不是正则语言。
事实上,这两种语言都是上下文无关语言,它的表达能力严格强于正则语言。
1.1.1 简介
文法(Grammar)用于描述一个语言。
一个上下文无关文法(Context-Free
Grammar,CFG)确定地形式化地描述了一个语言。(具体地,是一个上下文无关语言)
关于Context-Free:
有Context-Free(上下文无关)Grammar
也就有Context-Sensitive(上下文相关 /
上下文敏感)Grammar。
Context-Free Grammar的表达能力弱于Context-Sensitive Grammar。
为什么在《编译原理》课程中我们只学习上下文无关文法?
因为在实际几乎所有的现代编程语言的语法都是上下文无关的,因此使用CFG做语法分析就足够。
1.1.2...
2024-编译原理-词法篇
1 编译原理简介
### 1.1 编译器的工作
compiler
词法分析(Lexical Analysis)
语法分析(Syntax Analysis / Parsing)
语义分析(Semantic Analysis)
中间代码生成(Translating)
优化(Optimization)
代码生成(Code Generating)
1.2 关于IR
IR:Intermediate
Representation,中间表示,由编译器前端产生,被后端使用。
树型IR:如语法分析树、抽象语法树。
线性IR:如三地址码。
为什么要有IR?
统一编译成中间表示,从而分离开前端和后端,降低耦合
方便机器无关优化 (大量的优化 / 分析都在IR上进行)
1.3 串和语言
1.3.1 基本概念
字母表,一个有限的符号集合;
串,字母表中符号组成的一个有穷序列;
语言,给定字母表上一个任意可数的串的集合;
前缀 / 后缀 / 子串
真前缀 / 真后缀 / 真子串
空串,
1.3.2...
2024-NJUSE-编译原理
课程内容参考 https://qingkaishi.github.io/Compilers.html
目录
1 词法分析
2 语法分析
3 语义分析
4 中间代码生成
5 目标代码生成
6 代码优化
2024毕昇杯总结.md
...
backend-bugs
Backend Bugs
出现bug的源码:
12345678int foo() { return 5;}int main() { putint(foo()); return 0;}
目前生成的目标代码: (简化过)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051.data.textifElseIf:ifElseIfEntry: li a0, 5 ret.globl mainmain:mainEntry: # reserve space addi sp, sp, -4 # save caller saved regs addi sp, sp, -8 sd ra, 0(sp) # call ifElseIf call ifElseIf # restore caller saved regs ld ra, 0(sp) addi sp, sp, 8 # get address of...
Compilers 框架指南
Compilers 框架指南
1. 项目架构
Main 项目启动类,
在其main方法中完成从源代码到生成目标代码的全过程
frontend 在这里进行前端开发 (包括词法分析, 语法分析,
语义分析, ir生成)
ir 在这个包下模仿全部的llvm api
(7.1之后的工作重点)
test/java 测试驱动类存放在此目录下
test/resources 测试用例存放在此目录下
2. 前端开发指南
在main方法中加入与前端相关的代码.
目前的main方法已实现了命令行参数的解析, 如图:
前端的任务有以下:
当 emitLLVM 为 true 时, 能在
main
方法中生成一个类型为LLVMModuleRef临时变量,
代表翻译后得到的llvm ir.
1LLVMModuleRef module = ...;
如果用户开启了 --emit-llvm 选项, 输出llvm
ir到指定输出文件.
如果用户开启了 -O2 选项, 能够生成优化的llvm
ir.
借助 antlr 完成词法分析,...
Golang复习笔记
Golang复习笔记
1: intro
Golang: 极简单的部署方式
可直接编译成机器码
不依赖其它库
直接运行可部署
Golang是一门静态类型语言 -- 编译时可检查出隐藏的问题
语言层面的并发
天生支持并发
充分利用多核
123456789101112131415161718package mainimport ( "fmt" "time")func goFunc(i int) { fmt.Println("goroutine ", i, " ...")} func main() { for i := 0; i < 10000; i++ { go goFunc(i) // 开启一个并发协程 } time.Sleep(time.Second)}
强大的标准库
runtime系统调度机制
高效的GC...
Java复习笔记
Java复习笔记
Java-Lesson 0 (Resources)
Java 8 官方文档: https://docs.oracle.com/javase/8/docs/api/
Google Java Style Guide:
https://google.github.io/styleguide/javaguide.html
Java-Lesson 1 (Basic Grammar)
标识符: 标识类/ 变量/ 常量和方法的名字, 由字母 (A-Z, a-z) /
特殊符号($, _) 和数字 (0-9) 构成, 区分大小写,
名字的第一个字符不能为数字, 标识符不可为Java关键字.
Java数据类型可分为基本数据类型 ( Primitive type
)和引用数据类型 ( Reference type ),
数组和对象都是引用数据类型.
Java基本数据类型有byte: -128~127 (1 byte) 的整数,
boolean: 布尔型 (实际占1 byte), char: 占2
byte, (16-bit...
C语言复习笔记
C语言复习笔记
Lesson 1: 输入输出
program程序 Operations运算符 expressions表达式
statements语句
理解第一个程序hello.c的各个部分:
12345#include : preprocessor directive 预处理指令main: function 函数int main(): takes no arguments, return an integer 无参数, 返回整型main: .c contains one and only one main function 一个.c文件有且仅有一个main函数printf: print+f: format 格式化输出
%f或者%lf都表示匹配输出double类型的值;但是scanf输入只能使用%lf匹配
如果是输入输出的是long double类型, 对应的格式串是
%Lf.
const double PI; 定义常量,
常量要全大写命名。
% 和 f 中间可以有一些东西.
例如%10.2f这里的点不是小数点,...