中间语言设计目的
中间语言(IR, Intermediate Representation)是编译器前端和后端之间的桥梁:
- 便于生成目标代码:IR 接近机器指令格式,简化后端翻译
- 便于优化:IR 保留程序结构和数据流信息
- 便于移植:前端生成统一 IR,后端适配不同目标机
中间语言分类
中间语言
├── 逆波兰式(后缀式):无括号,栈式求值
├── N元式
│ ├── 三元式:结果用编号引用
│ ├── 间接三元式:间接码表+三元式表
│ └── 四元式:显式结果名
└── 图表示(DAG/语法树)
逆波兰式(后缀式)
运算对象在前,运算符在后,如 。
-
对机器友好:顺序扫描 + 栈处理
-
无需括号,优先级隐含在顺序中
-
控制流通过 BZ(假跳转)和 BR(无条件跳转)实现
重点 中缀转后缀是考试常见题型。
三元式
格式:(op, arg1, arg2)
- 结果用编号引用(如
(1)表示第 1 个三元式的结果) - 缺点:移动顺序时编号需调整
示例:
(1) (*, B, C)
(2) (+, A, (1))
间接三元式
- 间接码表 + 三元式表
- 间接码表指向三元式表
- 便于优化(共享相同子表达式)
四元式
格式:(op, arg1, arg2, result)
- 结果显式命名,便于优化
- 编译器常用形式
示例:
(*, B, C, T1)
(+, A, T1, T2)
中缀 → 后缀转换算法(双栈法 + 优先级)
使用运算符栈和输出队列:
- 操作数 → 直接输出
- 左括号 → 入栈
- 右括号 → 弹出至左括号,输出
- 运算符 → 弹出优先级 当前运算符者,再入栈
- 扫描结束 → 弹出栈中所有运算符
优先级:* / > + -
重点 中缀转后缀完整过程必须掌握。
示例:
| 当前符号 | 输出 | 运算符栈 |
|---|---|---|
| + | ||
| + | ||
| 结束 |