中间语言设计目的

中间语言(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)

中缀 → 后缀转换算法(双栈法 + 优先级)

使用运算符栈输出队列

  1. 操作数 → 直接输出
  2. 左括号 → 入栈
  3. 右括号 → 弹出至左括号,输出
  4. 运算符 → 弹出优先级 当前运算符者,再入栈
  5. 扫描结束 → 弹出栈中所有运算符

优先级:* / > + -

重点 中缀转后缀完整过程必须掌握。

示例:

当前符号输出运算符栈
+
+
结束