
说明语句的设计 例real idl,id2,id3 说明语句的文法 1.①→ TL T.type .in 类型2. → int real real 描述3.灯 》 real real 变量4. Li,id LI.in 表5. real id real ■要解决的问题 L2.in ide ◆记录标识符的类型 real real ◆类型信息传递 idi 继承属性自上 real 而下传递信息 023/2/28 KD
2023/2/28 1 说明语句的设计 例 real id1,id2,id3 说明语句的文法 1. D → T L 2. T → int 3. T → real 4. L → L1,id 5. L → id D T L real L1 , id3 L2 , id2 id1 要解决的问题 记录标识符的类型 类型信息传递 real real real .type real .in real .in real .in real 继承属性自上 而下传递信息 类型 描述 变量 表

说明语句的属性文法 ■用语义规则描述变量说明。 ■ 该属性文法描述如下: 产生式 语义规则(属性计算规则) 继承属性 1. D→TL ①.in:=T.type 2. T→int T.type:=integer 3. T→real T.type :real 综合属性 4. L→L1,id LI.in :L.in addtype(id.entry,L.in 5. L→id addtype(id.entry,L.in entry 单词id的属性,id在符号表的入口 addtype在符号表中为变量添加类型信息 2023/2/28 节目录 ☒
2023/2/28 2 1. D→TL L.in := T.type 2. T→int T .type := integer 3. T→real T.type := real 4. L→L1 ,id L1 .in := L.in addtype( id.entry, L.in ) 5. L→id addtype( id.entry, L.in ) entry 单词 id 的属性,id在符号表的入口 addtype 在符号表中为变量添加类型信息 用语义规则描述变量说明。 该属性文法描述如下: 产生式 语义规则(属性计算规则) 说明语句的属性文法 综合属性 继承属性 节目录

例real id1,id2,id3的语法树和属性计算pl72 D 依赖关系 (4) ⑤ 拓扑排序 T.type2real一 in=real t w.in-reat addtype real ⑥ real id.e® addtype real ⑨ L2.in=real,id2.entry 自下而上无 addtype real 法直接实现 ⑩ 自上而下存在左 idi.entry 递归,可改造 2023/2/28 节目录 ☒D3
2023/2/28 3 例real id1,id2,id3的语法树和属性计算 p172 D T L real L1 , id3 L2 , id2 id1 addtype .type=real .in=real .in=real .in=real 依赖关系 拓扑排序 自下而上无 法直接实现 .entry .entry .entry 自上而下存在左 递归,可改造 real addtype real addtype real ④ ⑤ ⑦ ⑥ ⑨ ⑧ ① ② ③ ⑩ 节目录

说明语句的翻译模式 将语义动作中的计算向前移,使继承属性 的计算出现在其文法符号之前 1. D→T{L.in:=T.type}L 2.T→int {T.type:=integer} 3. T-real {T.type:=real} 4.L-L1.in:=L.in}L1,id addtype(id.entry,L.in)} 5.L→id {addtype(id.entry,L.in)} 问题:如何自下而上计算继承属性? e20 23/2/28
2023/2/28 4 说明语句的翻译模式 将语义动作中的计算向前移,使继承属性 的计算出现在其文法符号之前 1. D→T {L.in:=T.type} L 2. T→int {T.type:=integer} 3. T→real {T.type:=real} 4. L→{L1.in:=L.in} L1,id {addtype(id.entry,L.in)} 5. L→id {addtype(id.entry, L.in)} 问题:如何自下而上计算继承属性?

自下而上计算继承属性p176 ■解决方法 从翻译模式中去掉嵌入在产生式中间的动作 1.D→T M L 2.T→int [T.type:=integer} 3.T→real {T.type:=real} 4.L→ N Ll,id {addtype(id.entry,L.in)} 5.L→id 引入6.Maddty(id.enttypb}in)} ■引入7.N→e{L.in:=L.in} 2023/2/28 I 5
2023/2/28 5 解决方法 从翻译模式中去掉嵌入在产生式中间的动作 自下而上计算继承属性 p176 1. D→T{L.in:=T.type}L 2. T→int {T.type:=integer} 3. T→real {T.type:=real} 4. L→{L1.in:=L.in}L1,id {addtype(id.entry,L.in)} 5. L→id 引入6. {addtype(id.entry,L.in)} M→ε {L.in:=T.type} 引入7. N→ε {L1.in:=L.in} M N

real id1,id2的翻译过程 1. D→TML T.type 2. T→int =real AL.in {T.type:=integer} T M=real 3.T→real {T.type:=real} 4. L→NLl,id LI.in N LI,id2 {addtype(id.entry,L.in)} real 5.L→id {addtype(id.entry,L.in)} 6.M-8 (L.in:=T.type} idl 7.N→e{L1.in:L.in real 023/2/28 节目绿☑
2023/2/28 6 real id1,id2的翻译过程 1. D→T M L 2. T→int {T.type:=integer} 3. T→real {T.type:=real} 4. L→N L1,id {addtype(id.entry,L.in)} 5. L→id {addtype(id.entry,L.in)} 6. M→ε{L.in:=T.type} 7. N→ε{L1.in:=L.in} D T M L real ε N L1 ,id2 ε id1 T.type =real L.in =real L1.in =real real real 节目录

8.7说明语句的翻译p196 ■翻译工作 ◆确定变量类型 ◆分配存储空间一一相对地址 0全局数据表示为静态数据区的偏移值 0局部数据表示为局部数据域(活动记录的 部分)的偏移值 ◆作用域 ■地址空间的分配方式 ◆设置一个全局量offset,记录当前可 用存储空间的开始地址,初值为0 ◆每次分配一个变量的空间,将offset 增加相应的值 2023/2/28 ☒D7
2023/2/28 7 8.7 说明语句的翻译 p196 翻译工作 确定变量类型 分配存储空间——相对地址 Ø 全局数据表示为静态数据区的偏移值 Ø 局部数据表示为局部数据域(活动记录的 部分)的偏移值 作用域 地址空间的分配方式 设置一个全局量offset,记录当前可 用存储空间的开始地址,初值为0 每次分配一个变量的空间,将offset 增加相应的值

例存储布局 ■设整数类型域宽为4 实数类型域宽为8 offset ■说明语句 x:array [8]of real; i:integer; X j:real; ■名字类型 相对地址 array(8,real)0 63 i integer 64 i j real 68 75 j 7 2023/2/28 ☒D8
2023/2/28 8 例 存储布局 设整数类型域宽为4 实数类型域宽为8 说明语句 x:array [8] of real; i:integer; j:real; 名字 类型 相对地址 0 offset 63 x 64 67 i 68 75 j 76 x array(8,real) 0 i integer 64 j real 68

翻译模式中变量和函数 类型描述符T的属性 ◆type类型 ◆width占用的字节数 ■语义函数 enter (name,type,offset) 在符号表中设置变量name的类型type和地址offset ◆array(num,type)描述数组类型 ◆pointer(type)描述指针类型 ■全局量 ◆offset跟踪下一个可用的相对地址的位置 2023/2/28 ☒9
2023/2/28 9 翻译模式中变量和函数 类型描述符T的属性 type 类型 width 占用的字节数 语义函数 enter(name,type,offset) 在符号表中设置变量name的类型type和地址offset array(num,type) 描述数组类型 pointer(type) 描述指针类型 全局量 offset 跟踪下一个可用的相对地址的位置

说明语句的翻译模式p196 (1)P→D {offset:=0} 说明段 (2)D→D:D{} 说明语句序列 (3)D→id:T 说明变量id类型为T enter (id.name,T.type,offset); offset:=offset+T.width (4)T-integer{T.type:=integer;T.width:=4 (⑤)T→real{T.type:real;T.width:=8} (6)T→array[num]ofT1数组 T.type:=array (num.val,T1.type); T.width:=num.val*T1.width (7)T→↑T1 指针 T.type:=pointer(T1.type ) T.width:=4} 2023/2/28 ☒D10
2023/2/28 10 说明语句的翻译模式 p196 (1)P→D (2)D→D;D (3)D→id:T (4)T→integer (5)T→real (6)T→array[num] of T1 (7)T→↑T1 说明段 说明语句序列 说明变量 id 类型为 T 数组 指针 {offset:=0} { } { enter(id.name,T.type,offset); offset:=offset+T.width } { T.type:=integer;T.width:=4 } { T.type:=real;T.width:=8 } { T.type:=array(num.val,T1.type); T.width:=num.val*T1.width } { T.type:=pointer( T1.type ); T.width:=4 }