具有受控副作用的语义规贝 按照依赖图的任何拓扑顺序进行属性计算都可以 产生同样的副作用 L→L;,idL1in=L.in; D addType(id entry, L in) L→id add Type(id entry, L in) T 力pe 5L6 int in l 8 3 3 entry in9 10 id 2 2 enti id1 1 entt
具有受控副作用的语义规则 • 按照依赖图的任何拓扑顺序进行属性计算都可以 产生同样的副作用 D int T , id3 L L L id2 id1 , 1 entry 10 2 entry 3 entry in 9 in 7 8 4 type in 5 6 L→ id addType(id.entry, L.in) L→ L1 , id L1 .in = L.in; addType(id.entry, L.in)
具有受控副作用的语义规贝 按照依赖图的任何拓扑顺序进行属性计算都可以 产生同样的副作用 产生式 语义规则 L→En print(E.val) E→E1+T E.val= e 1.val+ Tval E→T E.val= tval T→T*F Tval=Tr.val Fval T→F Tval= eval F→(E) Eval= e. val F→ digit Eval= digit. lexval
具有受控副作用的语义规则 • 按照依赖图的任何拓扑顺序进行属性计算都可以 产生同样的副作用 产 生 式 语 义 规 则 L → E n print (E.val) E → E1 + T E.val = E1 .val + T.val E → T E.val = T.val T → T1 F T.val = T1 .val F.val T → F T.val = F.val F→ (E) F.val = E.val F → digit F.val = digit.lexval
语义规则的计算方法 ·分析树方法:刚才介绍的方法,在编译过程中确 定计算次序,效率低 概念上的一般方法 ·考虑在编译前(在构造编译器时)决定计算次序, 不在编译时显式构造依赖图 (编译器实现者)对(编译器设计者提供的)语义规 则进行分析,静态确定计算次序 适用于手工构造编译器。属性依赖关系复杂的语法制导定义很难 事先确定属性计算次序 (编译器实现者)事先确定属性的计算策略(如边分 析边计算),(编译器设计者提供的)语义规则必须 符合所选分析方法的限制 适用于编译器的自动生成。限制语法制导定义的种类
语义规则的计算方法 • 分析树方法:刚才介绍的方法,在编译过程中确 定计算次序,效率低 概念上的一般方法 • 考虑在编译前(在构造编译器时)决定计算次序, 不在编译时显式构造依赖图 • (编译器实现者)对(编译器设计者提供的)语义规 则进行分析,静态确定计算次序 适用于手工构造编译器。属性依赖关系复杂的语法制导定义很难 事先确定属性计算次序 • (编译器实现者)事先确定属性的计算策略(如边分 析边计算),(编译器设计者提供的)语义规则必须 符合所选分析方法的限制 适用于编译器的自动生成。限制语法制导定义的种类
S属性定义的自底向上计算 ·例:语法树的构造 语法树是分析树的浓缩表示:算符和关键字不是作为 叶节点,而是作为内部节点 语法制导翻译可以基于分析树,也可以基于语法树 语法树的例子: if b then sl else s2 8+5米2 if-then-else B 2
S属性定义的自底向上计算 • 例:语法树的构造 • 语法树是分析树的浓缩表示:算符和关键字不是作为 叶节点,而是作为内部节点 • 语法制导翻译可以基于分析树,也可以基于语法树 • 语法树的例子: if B then S1 else S2 8 + 5 2 if-then-else B S1 S2 + * 5 2 8
构造语法树的语法制导定义 产生式 语义规则 E>E1+T Enptr=mkNode(+, Er.nptr, T nptr) E→T Enptr=Tnptr 7→T*FTp= mknode(·*,T,pm,F,pm) T→F Tnptr= Fnptr F→(E)F,npt=E,pt F→)id Fnptr= mkleaf(id, identry) F->num Fnptr= mkLeaf(num, num. val
构造语法树的语法制导定义 产 生 式 语 义 规 则 E → E1 + T E.nptr = mkNode( ‘+’, E1 .nptr, T.nptr) E → T E.nptr = T.nptr T → T1 F T.nptr = mkNode( ‘’, T1 .nptr, F.nptr) T → F T.nptr = F.nptr F → (E) F.nptr = E.nptr F → id F.nptr = mkLeaf (id, id.entry) F → num F.nptr = mkLeaf (num, num.val)