四元式:操作符与表示方法

四元式:操作符与表示方法

四元式基本概念

四元式是编译过程中使用的一种中间代码形式,它将代码分解为一系列基本操作,每个操作由四个部分组成:

1
(操作符, 操作数1, 操作数2, 结果)

这种结构类似于汇编语言,便于后续的代码优化和目标代码生成。

四元式操作符分类

1. 算术运算操作符

用于执行基本的数学运算:

操作符 含义 示例 说明
+ 加法 (+, a, b, t1) t1 = a + b
- 减法 (-, a, b, t1) t1 = a - b
* 乘法 (*, a, b, t1) t1 = a * b
/ 除法 (/, a, b, t1) t1 = a / b
% 取模 (%, a, b, t1) t1 = a % b
U- 一元负号 (U-, a, null, t1) t1 = -a

2. 关系运算操作符

用于比较两个值,结果通常是布尔值(0或1):

操作符 含义 示例 说明
> 大于 (>, a, b, t1) t1 = (a > b) ? 1 : 0
< 小于 (<, a, b, t1) t1 = (a < b) ? 1 : 0
>= 大于等于 (>=, a, b, t1) t1 = (a >= b) ? 1 : 0
<= 小于等于 (<=, a, b, t1) t1 = (a <= b) ? 1 : 0
== 等于 (==, a, b, t1) t1 = (a == b) ? 1 : 0
!= 不等于 (!=, a, b, t1) t1 = (a != b) ? 1 : 0

3. 逻辑运算操作符

用于执行布尔逻辑运算:

操作符 含义 示例 说明
&& 逻辑与 (&&, a, b, t1) t1 = a && b
|| 逻辑或 `(
! 逻辑非 (!, a, null, t1) t1 = !a

4. 赋值操作符

用于将值赋给变量:

操作符 含义 示例 说明
= 赋值 (=, a, null, b) b = a

5. 控制流操作符

用于控制程序的执行顺序:

操作符 含义 示例 说明
jmp 无条件跳转 (jmp, null, null, L1) 跳转到标签L1
jnz 非零跳转 (jnz, a, null, L1) 如果a≠0,跳转到L1
jz 零跳转 (jz, a, null, L1) 如果a=0,跳转到L1
je 等于跳转 (je, a, b, L1) 如果a==b,跳转到L1
jne 不等于跳转 (jne, a, b, L1) 如果a!=b,跳转到L1
jg 大于跳转 (jg, a, b, L1) 如果a>b,跳转到L1
jl 小于跳转 (jl, a, b, L1) 如果a<b,跳转到L1
jge 大于等于跳转 (jge, a, b, L1) 如果a>=b,跳转到L1
jle 小于等于跳转 (jle, a, b, L1) 如果a<=b,跳转到L1

6. 函数调用操作符

用于函数的调用和返回:

操作符 含义 示例 说明
param 参数传递 (param, a, null, null) 将a作为参数传递
call 函数调用 (call, func, null, t1) 调用函数func,结果存t1
ret 返回 (ret, a, null, null) 从函数返回a的值

7. 数组操作符

用于数组元素的访问:

操作符 含义 示例 说明
[] 数组访问 ([], arr, i, t1) t1 = arr[i]
[]= 数组赋值 ([]=, arr, i, val) arr[i] = val

8. 其他操作符

操作符 含义 示例 说明
label 标签定义 (label, null, null, L1) 定义标签L1
read 读操作 (read, null, null, a) 从输入读取值到a
write 写操作 (write, a, null, null) 将a的值输出

不同情况的表示方法示例

1. 表达式计算

对于表达式 x = (a + b) * c - d

1
2
3
4
(+, a, b, t1)      ; t1 = a + b
(*, t1, c, t2) ; t2 = t1 * c
(-, t2, d, t3) ; t3 = t2 - d
(=, t3, null, x) ; x = t3

2. 条件语句

对于 if (a > b) then x = 1 else x = 0

1
2
3
4
5
6
7
(>, a, b, t1)      ; t1 = (a > b) ? 1 : 0
(jz, t1, null, L1) ; 如果t1=0,跳转到L1
(=, 1, null, x) ; x = 1
(jmp, null, null, L2) ; 跳转到L2
(label, null, null, L1) ; 标签L1
(=, 0, null, x) ; x = 0
(label, null, null, L2) ; 标签L2

3. 循环语句

对于 while (i < 10) { i = i + 1; }

1
2
3
4
5
6
7
(label, null, null, L1) ; 循环开始标签
(<, i, 10, t1) ; t1 = (i < 10) ? 1 : 0
(jz, t1, null, L2) ; 如果i>=10,退出循环
(+, i, 1, t2) ; t2 = i + 1
(=, t2, null, i) ; i = t2
(jmp, null, null, L1) ; 跳回循环开始
(label, null, null, L2) ; 循环结束标签

4. 函数调用

对于 y = func(a, b)

1
2
3
(param, a, null, null) ; 传递第一个参数a
(param, b, null, null) ; 传递第二个参数b
(call, func, null, y) ; 调用函数func,结果存到y