第8章 中间代码与语法制导方法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
13年5月12日星期日
中间代码、语法制导方法
定义 中间代码:又称为中间语言,是复杂性介于源程序和机器语言 之间的一种表示形式。 常见的中间代码形式有逆波兰式、三元式、四元式、树等。 翻译方法分类 1.语法制导翻译 语法制导翻译方法是一种形式化方法,它严格依赖于产生式结 构,产生式发生变化,语法制导翻译程序也要随之发生变化,否则便 不能正常工作。 2.非语法制导翻译 非语法制导翻译方法不依赖于产生式,而只依赖于输入。无论 产生式(语法)怎么变化,只要输入不变,该翻译程序照样可以正常 工作。 注:语法可以任意变化,但应保证语法所生成的语言不变。
13年5月12日星期日
表达式的三元式及其语法制导生成
1. 三元式
(1)定义: 三元式的一般形式是: i:(ω,Opr1,Opr2) 其中:i为三元式编号;ω为运算符部分;Opr1和Opr2为 运算对象部分。 运算对象部分可以是变量名或三元式编号,如果是三元式 编号j,则表示该运算分量的值是对应三元式j的计算结果。 Tri(E):表示表达式E对应的三元式序列; Last(E):表示表达式E对应三元式序列中最后三元式编 号,如果E为一个变量x,则Last(E)=x。
13年5月12日星期日
表达式四元式元式及其语法制导生成
1. 基本概念 四元式的一般形式是: (ω,Opr1,Opr2,Result) 其中:ω为运算符部分;Opr1和Opr2为运算对象部分; Result是运算结果变量名。 运算对象部分可以是程序中定义的变量名或其它四元式生成 的临时结果变量名。 Four(E):表示表达式E对应的四元式序列; Res(E):表示表达式E的结果变量名。
注:语法分析程序应在归约之前调用相应语义子程序,然后再完成归约操作。
13年5月12日星期日
表达式的三元式及其语法制导生成 例:求表达式A*(B+C)对应的三元式序列。 解:求解过程如下:
Syn i F T T* T*( T*(i T*(F T*(T T*(E T*(E+ T*(E+i T*(E+F T*(E+T T*(E T*(E) T*F T E A A A A A AB AB AB AB AB ABC ABC A① A① A① ② ② Sem 输入流 A*(B+C) *(B+C) *(B+C) *(B+C) (B+C) B+C) +C) +C) +C) +C) C) ) ) ) ) A A A A A B B B B B C C C C C C C C 2:(*,A,①) 1:(+,B,C) id Trip
13年5月12日星期日
表达式四元式元式及其语法制导生成
2. 中缀式及其四元式定义
序号 1 产生式 E→T 中缀表达式 E=T Four(T) Res(E)=Res(T) Four(E(1)) Four(T) (+,Res(E(1)),Res(T),Temp) Res(E)=Temp Four(E(1)) Four(T) (-,Res(E(1)),Res(T),Temp) Res(E)=Temp Four(F) Res(T)=Res(F) Four(T(1)) Four(F) (*,Res(T(1)),Res(F),Temp) Res(T)=Temp Four(T(1)) Four(F) (/,Res(T(1)),Res(F),Temp) Res(T)=Temp 空 Res(E)=id Four(F) Res(F)=Res(E) 四元式
13年5月12日星期日
表达式的三元式及其语法制导生成
(2)中缀式及其三元式定义 文法G(E)的中缀式及其三元式定义如下:
序号 1 2 3 4 5 6 7 8 产生式 E→T E→E+T E→E-T T→F T→T*F T→T/F F→i F→(E) 中缀表达式 E=T E=E(1)+T E=E(1)-T T=F T=T(1)*F T=T(1)/F F=i F=(E) Tri(E)=Tri(T) Last(E)=Last(T) Tri(E)=Tri(E(1))ǁ‖Tri(T)ǁ‖i:(+,Last(E(1)),Last(T)) Last(E)=i (i是新三元式编号) Tri(E)=Tri(E(1))ǁ‖Tri(T)ǁ‖i:(-,Last(E(1)),Last(T)) Last(E)=i (i是新三元式编号) Tri(T)=Tri(F) Last(T)=Last(F) Tri(T)=Tri(T(1))ǁ‖Tri(F)ǁ‖i:(*,Last(T(1)),Last(F)) Last(T)=i (i是新三元式编号) Tri(T)=Tri(T(1))ǁ‖Tri(F)ǁ‖i:(/,Last(T(1)),Last(F)) Last(T)=i (i是新三元式编号) Tri(F)=空 Last(F)=id Tri(F)=Tri(E) Last(F)=Last(E) 逆波兰式
13年5月12日星期日
表达式的逆波兰式及其语法制导生成
根据上述定义,可将文法G(E)各产生式对应的逆波兰式定义写出,如下表: 序号 1 2 3 4 5 6 7 8 产生式 E→T E→E+T E→E-T T→F T→T*F T→T/F F →i F→(E) 中缀表达式 E=T E=E(1)+T E=E(1)-T T=F T=T(1)*F T=T(1)/F F=i F=(E) 逆波兰式 Pos(E)=Pos(T) Pos(E)=Pos(E(1))‖Pos(T)‖+ Pos(E)=Pos(E(1))‖Pos(T)‖Pos(T)=Pos(F) Pos(T)=Pos(T(1))‖Pos(F)‖* Pos(T)=Pos(T(1))‖Pos(F)‖/ Pos(F)=i Pos(F)=Pos(E)
13年5月12日星期日
表达式的三元式及其语法制导生成
算法:
序号 1 2 3 4 5 6 7 8 产生式 E→T E→E+T E→E-T T→F T→T*F T→T/F F→i F→(E) 空 GenTrip(+); GenTrip(-); 空 GenTrip(*); GenTrip(/); Sem[s]=id;s++; 空 语义子程序
13年5月12日星期日
中间代码、语法制导方法
该文法中,可用B.Vers表示串B的逆串,则: G(B): 1.B→a B.Vers=a 2.B→b B.Vers=b 3.B(1)→B(2)a B(1).Vers=a^B(2).Vers 4.B(1)→B(2)b B(1).Vers=b^B(2).Vers 按照上述规则求输入串的逆串计算过程如图所 示: 上述过程首先通过语法分析建立句子abb对应的 语法树,然后从叶子结点向树根逐步求每个非终结 符对应的逆串B.Vers,最后树根对应的逆串B.Vers 记为整个句子的逆串。
13年5月12日星期日
表达式的逆波兰式及其语法制导生成
如果设置一个逆波兰式区,将生成的逆波兰式依次放在该区中,便不需 进行逆波兰式之间的捻接错作,文法G(E)各语义子程序便更加简单,如 下表: 序号 1 2 3 4 5 6 7 8 产生式 E→T E→E+T E→E-T T→F T→T*F T→T/F F →i F→(E) 语义子程序 空 Write(+) Write(-) 空 Write(*) Write(/) Write(id) 空
13年5月12日星期日
表达式的三元式及其语法制导生成
(3)语法制导翻译算法 定义: 语义栈(记为Sem):用于存放运算对象信息,即变量标识符的地址或 三元式编号;堆栈指针为s,栈顶元素为Sem[s-1]。 语法栈(记为Syn):用于进行语法分析;堆栈指针为k,栈顶元素为 Syn[k-1]。 三元式区(记为Trip):用于存放生成的三元式序列;指针为j,Trip[j] 为下一个生成的三元式应该写入的空位置。 引入生成三元式的函数: Void GenTrip(ω) { Trip[j]=(ω,Sem[s-2],Sem[s-1]); Sem[s-2]=j; j++; s--; }
13年5月12日星期日
表达式的逆波兰式及其语法制导生成
逆波兰式又称为后缀表达式,例如A*B的逆波兰式为AB*,A +B*C的逆波兰式为ABC*+。 逆波兰式主要用于表达式的中间代码生成,仍考虑上节给出 的文法G(E): 1.E→T 2.E→E+T 3.E→E-T 4.T→F 5.T→T*F 6.T→T/F 7.F→i 8.F→(E) 这里用Pos(E)表示中缀表达式E对应的逆波兰式,因此,当 E=E1ωT时,有: Pos(E)=Pos(E1)‖Pos(T)‖ω 其中,运算“‖”定义为串的“捻接”。
第八章 中间代码与语法制导方法
1. 2. 3. 4. 5. 中间代码与语法制导方法 表达式的逆波兰式及其语法制导生成 表达式的三元式和语法制导生成 表达式的四元式及其语法制导生成 语句的中间代码及其语法制导生成
13年5月12日星期日
编译中的语义处理包含两方面内容: 1.审查每个语法结构的静态语义,即验证语 法结构合法的程序是否真正有意义,称为静态语义 分析或静态审查; 2.如果静态语义正确,语义处理则要执行真 正的翻译,即要么生成程序的一种中间表示形式 (中间代码),要么生成实际的目标代码。
A A A A A AB AB AB AB AB ABC ABC ABC+ ABC+ ABC+ ABC+* ABC+*
13年5月12日星期日
表达式的逆波兰式及其语法制导生成
小结: 理解语法制导翻译方法的基本概念,掌握表达 式的逆波兰式表示法及其语法制导生成方法,能够写 出给定表达式的逆波兰式翻译过程。
例: Pos(A+B*C)=Pos(A)‖Pos(B*C)‖+=ABC*+ Pos(A*B+C)=Pos(A*B)‖Pos(C)‖+=AB*C+
13年5月12日星期日
表达式的逆波兰式及其语法制导生成
由于上述文法G(E)共包含8个产生式,因此在设 计翻译程序时需定义8个语义子程序。 调用对应语义子程序时,已生成相应语法对象的逆 波兰式,操作时应按照先调用后归约的顺序进行,语义 子程序要完成的工作只是将各语法对象对应的逆波兰式 以及文法终结符按照产生式对应的逆波兰式定义链接起 来生成新的逆波兰式即可。
注:文法中的符号i是一个语法符号,是标识符的抽象表示,并不表示 具体的标识符,因此语义子程序在翻译时不能将i写入逆波兰式,而应根 据到Token表中查找其具体信息,这里用id表示标识符自身。
13年5来自百度文库12日星期日
表达式的逆波兰式及其语法制导生成
例:A*(B+C)的翻译过程:
序号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 语法栈 # #A #F #T #T* #T*( #T*(B #T*(F #T*(T #T*(E #T*(E+ #T*(E+C #T*(E+F #T*(E+T #T*(E #T*(E) #T*F #T #E 输入流 A*(B+C)# *(B+C)# *(B+C)# *(B+C)# (B+C)# B+C)# +C)# +C)# +C)# +C)# C)# )# )# )# )# # # # # 动作 移进 归约7 归约4 移进 移进 移进 归约7 归约4 归约1 移进 移进 归约7 归约4 归约2 移进 归约8 归约5 归约1 完成 逆波兰式区
13年5月12日星期日
表达式的三元式及其语法制导生成
例:求下列中缀表达式对应的三元式序列: ① A*B+C ② A*B+C/D ③ A∨B∧x≠y+1∨(x≥0∨B)∧D 解:
A*B+C 1:(*,A,B) 2:(+,①,C) 三 元 式 序 列 A*B+C/D 1:(*,A,B) 2:(/,C,D) 3:(+,①,②) A∨B∧x≠y+1∨(x≥0∨B)∧D 1:(+,y,1) 2:(≠,x,①) 3:(∧,B,②) 4:(∨,A,③) 5:(≥,x,0) 6:(∨,⑤,B) 7:(∧,⑥,D) 8:(∨,④,⑦)
13年5月12日星期日
中间代码、语法制导方法
例:考虑文法G(B): 1.B→a 2.B→b 3.B→Ba 4.B→Bb 设计一个翻译程序,将L(G(B))的任一符号串翻译成其逆 串,如将abb翻译成bba。 分析: 语法制导翻译方法是严格地根据文法产生式导出翻译程序的一 种翻译方法。实现时应对每个产生式设计相应子程序(称为语义子 程序)用于实现自己那部分的翻译工作。 翻译过程中,当一个产生式被用于匹配(自顶向下)或归约 (自底向上)时,调用相应的语义子程序进行翻译。