【编译原理】语句的翻译

目录

数组

if

while

while、if、数组


数组

三维数组

LOC(A[i,j,k])=base+(((i-low1)*n2+j-low2)*n3+k-low3)*w

=((i*n2+j)*n3+k)*w+base-((low1*n2+low2)*n3+low3)*w

数组 A 是一个三维数组,维度为 n1 × n2 × n3,low1、low2、low3,每个元素占 w 个字节空间,基地址为 A(常量)

数组 B 是一个二维数组,维度为 m1 × m2,low1、low2、low3,每个元素占 w 个字节空间(与 A 相同),基地址为 B(常量)

C_A = base_A - ((low1_A×n2 + low2_A)×n3 + low3_A)×w

C_B = base_B - (low1_B×m2 + low2_B)×w

  1. 计算 A[x][y][z] 的地址并加载其值。

  2. 计算 B[i][j] 的地址并存储加载的值。

// 计算 A[x][y][z] 的值

T1 = x * n2 (1)(*,x,n2,T1)

T1 = T1 + y (2)(+,T1,y,T1)

T2 = T1 * n3 (3)(*,T1,n3,T2)

T2 = T2 + z (4)(+,T2,z,T2)

T3=A - C_A (5)(-,A,C_A,T3)

T4=T2 * w (6)(*,T2,w,T4)

T5=T3[T4] (7)(=[ ],T3,T4,T5)

// 计算 B[i][j] 的地址并存储

T6 = i * m2 (8)(*,i,m2,T6)

T6 = T6 + j (9)(+,T6,j,T6)

T7=B - C_B (10)(-,B,C_B,T7)

T8=T6 * w (11)(*,T6,w,T8)

T7[T8]=T5 (12)([ ]=,T5,T7,T8)

四元式设计

  • (=[], base, offset, result):加载操作,等价于 result = *(base + offset)

  • ([]=, value, base, offset):存储操作,等价于 *(base + offset) = value

  • 常量 C_AC_B 在编译时计算,作为常量操作数使用

if

if(a>b and c>d) x=x+1;

else x=x-1;

三地址码

// 检查第一个条件 a>b

if a > b goto L1

goto E.false // 第一个条件不满足,直接跳转到 false 分支

// 检查第二个条件 c>d

L1: if c > d goto E.true

goto E.false // 第二个条件不满足,跳转到 false 分支

// true 分支

E.true: x=x+1;

goto E.next // 跳过 false 分支

// false 分支

E.false: x=x-1;

goto E.next // 可省略,因为 E.next 紧接其后

// 后续代码

E.next:

四元式

100 (j>, a, b, 102) // 检查 a>b,成立则跳转到 L1 (102)

101 (j, _, _, 107) // 否则跳转到 E.false (107)

// L1 标签位置 (102)

102 (j>, c, d, 104) // 检查 c>d,成立则跳转到 E.true (104)

103 (j, _, _, 107) // 否则跳转到 E.false (107)

// E.true 分支

104 (+, x, 1, T1) // 计算 x+1

105 (=, T1, _, x) // x = x+1

106 (j, _, _, 109) // 跳转到 E.next (109)

// E.false 分支

107 (-, x, 1, T2) // 计算 x-1

108 (=, T2, _, x) // x = x-1

// E.next 标签位置 (109)

109

while

while、if、数组

while (a > b or c > d) {

if (x == 0)

y = A[i][j];

else

y = A[i][k];

}

  1. 数组 A 是二维数组,维度为 n1 × n2,索引从 low1low2 开始

  2. 每个元素占 w 个字节,基地址为 A

  3. 常量 C_A = A - (low1 * n2 + low2) * w(编译时计算)

  4. 变量 a, b, c, d, x, i, j, k 已定义

三地址码

//while条件检查

LE: if a>b goto E.true

goto L

L: if c>d goto E.true

goto E.false

E.true: if x==0 goto F.true

goto F.false

F.true: T1=i*n2

T1=T1+j

T2=A-C_A

T3=T1*w

y=T2[T3]

goto F.next

F.false: T4-=i*n2

T4=T4+k

T5=A-C_A

T6=T4*w

y=T5[T6]

goto F.next

F.next:

goto LE

E.false:

四元式

100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)

101 (j, _, _, 102) // 否则跳转到 L (102)

102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)

103 (j, _, _, 118) // 否则跳转到 E.false (118)

104 (j==, x, 0, 106) // if x==0 成立,跳转到 F.true (106)

105 (j, _, _, 110) // 否则跳转到 F.false (110)

106 (*, i, n2, T1) // F.true: T1 = i*n2

107 (+, T1, j, T1) // T1 = T1 + j

108 (*, T1, w, T3) // T3 = T1*w (字节偏移)

109 (=[], T2, T3, y) // y = T2[T3] (加载 A[i][j])

110 (j, _, _, 114) // 跳转到 F.next (114)

111 (*, i, n2, T4) // F.false: T4 = i*n2 (注意:这里应该是 111)

112 (+, T4, k, T4) // T4 = T4 + k

113 (*, T4, w, T6) // T6 = T4*w (字节偏移)

114 (=[], T5, T6, y) // y = T5[T6] (加载 A[i][k])

115 (j, _, _, 100) // F.next: 跳回 LE (100)

118 E.false: // 循环结束

优化

  • 基地址计算 T_base = A - C_A 应该提到 E.true

  • 这样可以避免在两个分支中重复计算

// 优化后的四元式序列

100 (j>, a, b, 104) // if a>b

101 (j, _, _, 102) // else

102 (j>, c, d, 104) // if c>d

103 (j, _, _, 118) // else

104 (-, A, C_A, T_base) // E.true: 基地址计算 (提到这里!)

105 (j==, x, 0, 107) // if x==0

106 (j, _, _, 111) // else

107 (*, i, n2, T1) // F.true: T1 = i*n2

108 (+, T1, j, T1) // T1 += j

109 (*, T1, w, T_offset) // T_offset = T1*w

110 (=[], T_base, T_offset, y) // y = T_base[T_offset]

111 (j, _, _, 115) // 跳转到 F.next

112 (*, i, n2, T4) // F.false: T4 = i*n2 (112)

113 (+, T4, k, T4) // T4 += k

114 (*, T4, w, T_offset) // T_offset = T4*w

115 (=[], T_base, T_offset, y) // y = T_base[T_offset] (115)

116 (j, _, _, 100) // F.next: 跳回 LE

118 E.false: // 循环结束

while (a > b or c > d) {

if (x == 0) {

y = A[i][j] * 2;

z = B[k][m] + 1;

} else {

y = A[i][k] / 3;

z = B[k][n] - 1;

}

a = a - 1;

}

  1. 数组 A 是二维数组,维度为 n1A × n2A,下界为 low1A, low2A

  2. 数组 B 是二维数组,维度为 n1B × n2B,下界为 low1B, low2B

  3. 每个元素占 w 个字节

  4. 常量:

    • C_A = (low1A * n2A + low2A) * w

    • C_B = (low1B * n2B + low2B) * w

  5. 变量 a, b, c, d, x, i, j, k, m, n, y, z 已定义

// While 条件检查 (a > b or c > d)

LE:

if a > b goto E.true

goto L1

L1:

if c > d goto E.true

goto E.false

// 循环体开始

E.true:

T_baseA = A - C_A // 数组 A 的基地址

T_baseB = B - C_B // 数组 B 的基地址

if x == 0 goto F.true

goto F.false

// if true 分支

F.true:

// y = A[i][j] * 2

T1 = i * n2A

T1 = T1 + j

T2 = T1 * w

T3 = T_baseA[T2]

T4 = T3 * 2

y = T4

// z = B[k][m] + 1

T5 = k * n2B

T5 = T5 + m

T6 = T5 * w

T7 = T_baseB[T6]

T8 = T7 + 1

z = T8

goto F.next

// if false 分支

F.false:

// y = A[i][k] / 3

T9 = i * n2A

T9 = T9 + k

T10 = T9 * w

T11 = T_baseA[T10]

T12 = T11 / 3

y = T12

// z = B[k][n] - 1

T13 = k * n2B

T13 = T13 + n

T14 = T13 * w

T15 = T_baseB[T14]

T16 = T15 - 1

z = T16

goto F.next

// 循环尾部

F.next:

a = a - 1

goto LE

// 循环结束

E.false:

100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)

101 (j, _, _, 102) // 否则跳转到 L1 (102)

102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)

103 (j, _, _, 150) // 否则跳转到 E.false (150)

// E.true: 计算基地址

104 (-, A, C_A, T_baseA) // T_baseA = A - C_A

105 (-, B, C_B, T_baseB) // T_baseB = B - C_B

106 (j==, x, 0, 109) // if x==0 成立,跳转到 F.true (109)

107 (j, _, _, 120) // 否则跳转到 F.false (120)

// F.true: y = A[i][j] * 2

108 (*, i, n2A, T1) // T1 = i * n2A

109 (+, T1, j, T1) // T1 = T1 + j

110 (*, T1, w, T2) // T2 = T1 * w

111 (=[], T_baseA, T2, T3) // T3 = A[i][j]

112 (*, T3, 2, T4) // T4 = T3 * 2

113 (=, T4, _, y) // y = T4

// z = B[k][m] + 1

114 (*, k, n2B, T5) // T5 = k * n2B

115 (+, T5, m, T5) // T5 = T5 + m

116 (*, T5, w, T6) // T6 = T5 * w

117 (=[], T_baseB, T6, T7) // T7 = B[k][m]

118 (+, T7, 1, T8) // T8 = T7 + 1

119 (=, T8, _, z) // z = T8

120 (j, _, _, 136) // 跳转到 F.next (136)

// F.false: y = A[i][k] / 3

121 (*, i, n2A, T9) // T9 = i * n2A

122 (+, T9, k, T9) // T9 = T9 + k

123 (*, T9, w, T10) // T10 = T9 * w

124 (=[], T_baseA, T10, T11) // T11 = A[i][k]

125 (/, T11, 3, T12) // T12 = T11 / 3

126 (=, T12, _, y) // y = T12

// z = B[k][n] - 1

127 (*, k, n2B, T13) // T13 = k * n2B

128 (+, T13, n, T13) // T13 = T13 + n

129 (*, T13, w, T14) // T14 = T13 * w

130 (=[], T_baseB, T14, T15) // T15 = B[k][n]

131 (-, T15, 1, T16) // T16 = T15 - 1

132 (=, T16, _, z) // z = T16

// F.next: 循环尾部

133 (-, a, 1, a) // a = a - 1

134 (j, _, _, 100) // 跳回 LE (100)

// E.false: 循环结束

150

数组访问优化

  • 第 104-105 行:在循环体开始处计算数组基地址(避免重复计算)

  • 两个分支共享相同的基地址寄存器

  • 地址计算:(行索引 * 列数 + 列索引) * 元素大小

100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)

101 (j, _, _, 102) // 否则跳转到 L1 (102)

102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)

103 (j, _, _, 150) // 否则跳转到 E.false (150)

// E.true: 计算数组基地址

104 (*, low1A, n2A, T_temp1) // T_temp1 = low1A * n2A

105 (+, T_temp1, low2A, T_temp1) // T_temp1 += low2A

106 (*, T_temp1, n3A, T_temp1) // 三维数组需*n3,二维可省略

107 (*, T_temp1, w, T_temp1) // T_temp1 *= w

108 (-, A, T_temp1, T_baseA) // T_baseA = A - T_temp1 (A的调整基址)

109 (*, low1B, n2B, T_temp2) // T_temp2 = low1B * n2B

110 (+, T_temp2, low2B, T_temp2) // T_temp2 += low2B

111 (*, T_temp2, w, T_temp2) // T_temp2 *= w

112 (-, B, T_temp2, T_baseB) // T_baseB = B - T_temp2 (B的调整基址)

113 (j==, x, 0, 116) // if x==0 成立,跳转到 F.true (116)

114 (j, _, _, 127) // 否则跳转到 F.false (127)

// F.true: y = A[i][j] * 2

115 (*, i, n2A, T1) // T1 = i * n2A

116 (+, T1, j, T1) // T1 = T1 + j

117 (*, T1, w, T2) // T2 = T1 * w (字节偏移)

118 (=[], T_baseA, T2, T3) // T3 = A[i][j]

119 (*, T3, 2, T4) // T4 = T3 * 2

120 (=, T4, _, y) // y = T4

// z = B[k][m] + 1

121 (*, k, n2B, T5) // T5 = k * n2B

122 (+, T5, m, T5) // T5 = T5 + m

123 (*, T5, w, T6) // T6 = T5 * w (字节偏移)

124 (=[], T_baseB, T6, T7) // T7 = B[k][m]

125 (+, T7, 1, T8) // T8 = T7 + 1

126 (=, T8, _, z) // z = T8

127 (j, _, _, 143) // 跳转到 F.next (143)

// F.false: y = A[i][k] / 3

128 (*, i, n2A, T9) // T9 = i * n2A

129 (+, T9, k, T9) // T9 = T9 + k

130 (*, T9, w, T10) // T10 = T9 * w (字节偏移)

131 (=[], T_baseA, T10, T11) // T11 = A[i][k]

132 (/, T11, 3, T12) // T12 = T11 / 3

133 (=, T12, _, y) // y = T12

// z = B[k][n] - 1

134 (*, k, n2B, T13) // T13 = k * n2B

135 (+, T13, n, T13) // T13 = T13 + n

136 (*, T13, w, T14) // T14 = T13 * w (字节偏移)

137 (=[], T_baseB, T14, T15) // T15 = B[k][n]

138 (-, T15, 1, T16) // T16 = T15 - 1

139 (=, T16, _, z) // z = T16

// F.next: 循环尾部

140 (-, a, 1, a) // a = a - 1

141 (j, _, _, 100) // 跳回 LE (100)

// E.false: 循环结束

150

基地址计算完整体现

  • 第 104-108 行:完整计算 T_baseA = A - ((low1A * n2A + low2A) * w)

  • 第 109-112 行:完整计算 T_baseB = B - ((low1B * n2B + low2B) * w)

  • 使用临时变量 T_temp1T_temp2 存储中间结果

相关推荐
辉辉还没睡14 分钟前
Lora训练
人工智能·算法·机器学习
电院大学僧2 小时前
初学python的我开始Leetcode题10-2
python·算法·leetcode
码破苍穹ovo3 小时前
二分查找----1.搜索插入位置
数据结构·算法
烨然若神人~4 小时前
算法第38天|322.零钱兑换\139. 单词拆分
算法
sukalot5 小时前
window显示驱动开发—输出合并器阶段
驱动开发·算法
Xの哲學5 小时前
hostapd 驱动注册机制深度分析
linux·网络·算法·wireless
int型码农6 小时前
数据结构第八章(六)-置换选择排序和最佳归并树
java·c语言·数据结构·算法·排序算法
@我漫长的孤独流浪6 小时前
数据结构----排序(3)
数据结构·c++·算法
依然易冷7 小时前
【APR-自动代码修复】论文分享:PyTy
算法