1 、编译器简介
一、基础🧀
- 编译器是一个程序,把源代码变成目标代码
- 源代码是指比如C++,Java
- 目标代码是指比如×86,ARM,MIPS
flowchart LR
A["源代码"] --> B["编译器"]
B -->|静态计算| C["目标程序"]
C --> D["计算机"]
D -->|动态计算| E["计算结果"]
- 解释器也是一种程序,但是输出和编译器不一样
flowchart TB
I1["I"] --> C["C"] --> O1["O:可执行程序"]
I2["I"] --> INT["I"] --> O2["O:结果"]
style C fill:#fff,stroke:#333,stroke-width:2px
style INT fill:#fff,stroke:#333,stroke-width:2px 二、结构🧀
编译器是由多个阶段构成的流水线结构
flowchart TB
S["字符序列"] --> L["词法分析"]
L -->|记号序列| P["语法分析"]
P -->|抽象语法树| M["语义分析"]
M -->|中间代码| G["代码生成"]
G --> T["目标代码"]
ST["符号表"]
ST --- L
ST --- P
ST --- M
ST --- G
style S fill:none,stroke:none,color:#3344cc
style T fill:none,stroke:none,color:#3344cc
style L fill:#ffffff,stroke:#555,stroke-width:1.5px
style P fill:#ffffff,stroke:#555,stroke-width:1.5px
style M fill:#ffffff,stroke:#555,stroke-width:1.5px
style G fill:#ffffff,stroke:#555,stroke-width:1.5px
style ST fill:#ffffff,stroke:#555,stroke-width:1.5px 没有优化的编译器
flowchart TB
S["源代码"] --> A["词法分析"]
A -->|记号| B["语法分析"]
B -->|动作| C["语法树构造"]
C -->|抽象语法树| D["语义分析"]
D -->|中间树| E["翻译"]
E -->|中间树| F["正规化"]
F -->|中间树| G["指令选择"]
G -->|抽象汇编| H["控制流分析"]
H -->|控制流图| I["数据流分析"]
I -->|寄存器分配| J["代码生成"]
J -->|汇编代码| K["汇编器"]
K -->|可重定位目标代码| L["连接器"]
L --> T["可执行代码"]
style S fill:none,stroke:none
style T fill:none,stroke:none
style A fill:#fff,stroke:#222,stroke-width:2px
style B fill:#fff,stroke:#222,stroke-width:2px
style C fill:#fff,stroke:#222,stroke-width:2px
style D fill:#fff,stroke:#222,stroke-width:2px
style E fill:#fff,stroke:#222,stroke-width:2px
style F fill:#fff,stroke:#222,stroke-width:2px
style G fill:#fff,stroke:#222,stroke-width:2px
style H fill:#fff,stroke:#222,stroke-width:2px
style I fill:#fff,stroke:#222,stroke-width:2px
style J fill:#fff,stroke:#222,stroke-width:2px
style K fill:#fff,stroke:#222,stroke-width:2px
style L fill:#fff,stroke:#222,stroke-width:2px 更加复杂的编译器
把表达式 1+2+3 编译成栈式计算机指令
首先,编译器前端对源程序进行词法、语法和语义分析,构造抽象语法树。由于加法通常按左结合处理,因此表达式会被解析为:
对应的抽象语法树为:
随后,代码生成器按抽象语法树的后序遍历顺序生成栈式指令
执行过程是:先将 1 和 2 压栈,执行 add 得到 3;再将常量 3 压栈,再次执行 add,最终栈顶结果为 6
三、简单实例🧀
1、源语言🧀
加法表达式语言 Sum
- 两种语法形式
- 整形数字 \(n\)
- 加法 \(e_1+e_2\)
2、栈式计算机 Stack🧀
- 一个操作数栈
- 两条指令
- 压栈指令:
push n - 加法指令:
add
- 压栈指令: