1 / 51

第六章 语义分析和语法制导翻译

第六章 语义分析和语法制导翻译. 语义分析的任务:检查语义错误 类型检查: 运算数类型 一致性检查: 名字声明与引用 控制流检查: 转移目标 名字检查: 作用域 翻译的任务:建立等价的目标程序 生成中间语言的指令序列 名字绑定: 变量名、过程名 建立运行环境. 6.1 属性文法. 语义分析与语法制导翻译的描述方法 属性文法的定义: A=(G,V,F) G 是上下文无关文法 V 属性的有穷集 F 关于属性的断言和谓词. 用法. 针对语义,为文法符号设置属性 终结符使用单词的属性 为每个产生式设置语义规则 通过描述各属性的关系

efrem
Download Presentation

第六章 语义分析和语法制导翻译

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第六章 语义分析和语法制导翻译 • 语义分析的任务:检查语义错误 • 类型检查: 运算数类型 • 一致性检查: 名字声明与引用 • 控制流检查: 转移目标 • 名字检查: 作用域 • 翻译的任务:建立等价的目标程序 • 生成中间语言的指令序列 • 名字绑定: 变量名、过程名 • 建立运行环境

  2. 6.1 属性文法 语义分析与语法制导翻译的描述方法 • 属性文法的定义: • A=(G,V,F) • G 是上下文无关文法 • V 属性的有穷集 • F 关于属性的断言和谓词

  3. 用法 • 针对语义,为文法符号设置属性 • 终结符使用单词的属性 • 为每个产生式设置语义规则 • 通过描述各属性的关系 • 将语义分析和翻译步骤定义为产生式的断言和谓词

  4. 例6-1: 计算器的算法设计 • 需求:算术表达式的求值 • 设计: • 编制算术表达式的文法 • 引入属性表示语义信息 • 将值 val 作为表达式 E、项 T 和因子 F 的属性 • 用语义规则描述表达式的求值

  5. 属性文法(语法制导定义) • attr 是单词 digit 的属性 • print( val ) 是输出函数

  6. 例6-2:说明语句的类型信息统计 • 说明语句的作用 • 支持语义分析,提供语义检查的依据 • 设计 • 编写说明语句的文法 • 将类型信息作为类型描述 T 的属性 type 和变量表 L 的属性 in。 • 目的 • 分析说明语句 D,获取变量的类型信息

  7. 描述类型信息提取的属性文法 • entry 单词 id 的属性(符号表入口) • addtype 在符号表中为变量填加类型信息

  8. 属性文法的作用 • 抽象描述语义处理的要求 • 语义信息及其计算关系 • 适用于各种语义处理(分析、翻译、计算) • 语义处理的步骤 • 属性求值计算、断言检查 • 语义处理算法的描述方法 • 一种通用的语义处理算法设计方法

  9. 属性分类: • 综合属性 • 从其子结点的属性值计算出来的; • 如:E.val、T.type • 继承属性 • 从其兄弟结点和父结点的属性值计算出来的 • 如:L.in • 固有属性(单词属性)

  10. 属性的计算 • 构造语法分析树,填加响应的语义规则 • 综合属性 • 自底向上按照语义规则来计算各结点的综合属性值 • 继承属性 • 需要探讨计算次序

  11. 例6-3:3*5+4 的语法树与属性计算

  12. 例6-4:real id1,id2,id3 的分析树和属性计算 addtype addtype addtype

  13. S-属性定义: • 仅包括综合属性 • 对于所有A → X1X2…Xn, • A的属性计算仅用X1…Xn的属性 • 如:算术表达式求值的属性文法

  14. L-属性定义: • 其属性可用深度优先的顺序从左至右计算 • 对于所有 A→X1X2…Xn • Xi属性计算仅使用A X1X2…Xi-1的属性 • 如:说明语句的属性文法

  15. 翻译模式(Translation Schemes) • 特征 • 规定在语法分析中使用语义规则进行计算的次序 • 保证当动作使用某属性时,该属性必须是可用的 • 实现方法 • 将语义动作插入到产生式中的某个位置

  16. 例6-5:建立说明语句的翻译方案 • 将语义动作中的计算向前移,使继承属性的计算出现在其文法符号之前

  17. 翻译模式的设计 D → T { L.in := T.type } L T → int { T.type := integer } T → real { T.type := real } L → { L1.in := L.in } L1 , id { addtype(id.entry, L.in) } L → id { addtype(id.entry, L.in) }

  18. 习题 1. 下列文法是一个二进制数的文法。试根据该文法,编写一个语法制导定义,描述由 S 生成的二进制数的数值计算。 S -> L . L L -> L B | B B -> 0 | 1 2. 参照下列表达式文法编写语法制导定义,描述表达式的类型计算。要求在不同精度的数的计算中,结果取精度高的类型。 E -> E + T | T T -> n.n | n

  19. 6.2 中间语言 • 用于编译程序 • 源程序经过语义分析被译成中间代码序列 • (中间语言的语句) • 用中间语言过渡的好处: • 便于编译系统的实现、移植、代码优化

  20. 常用的中间语言 • 三地址代码(四元式) • 语法结构树(三元式) • 后缀式 特点 • 形式简单、语义明确、便于翻译 • 独立于目标语言

  21. 语法制导编译 描述方法 • 利用属性文法描述如何将各种语句和表达式翻译成中间代码 工作方式 • 分析与综合并行进行 • 每识别出一个语言结构时, • 完成相应的语义检查与中间代码生成

  22. 语法结构树 • 例 6-5:表达式 (A - 12) * B + 6 的语法结构树

  23. 将赋值语句变换为语法结构树 • 设置属性: • E.p 是语法结构树指针 • id.entry 是名字的表项入口 • num.val 是数值 • 树构造函数 • mknode 建中间结点 • mkleaf 建叶结点

  24. 生成语法树的属性文法

  25. 例6-6:a := b * (- c) + b * (- 34) 的语法结构树 root := * - 0 id a id b id c + * - 0 id b num 34

  26. 地址 算符 操作数 操作数 0 1 2 3 4 5 6 7 8 9 10 语法结构树的三元式表示

  27. 三地址代码 一般形式 x := y op z • 其中 x, y, z 为变量名、常数或编译产生的临时变量 • 四元式(op, x, y, z) 种类:x := y op z 双目运算 x := op y 单目运算 x := y 赋值 if x relop y goto l 条件转移

  28. 其他三地址代码 goto l 无条件转移 param x 实在参数 call p, n (n是参数个数) 过程调用 return x 过程返回 x := y[i] 数组运算 x[i] := y x := &y 指针运算 x := *y *x = y

  29. 6.3赋值语句的翻译 翻译的需求 • 充分了解各种语言现象的语义 • 包括:控制结构、数据结构、单词 • 充分了解它们的实现方法 • 目标语言的语义 • 了解中间代码的语义 • 了解运行环境

  30. 实现赋值语句的翻译 语义过程 • 产生一条中间代码 gen(code) • 产生新的临时变量 newtemp 属性设置 • 中间代码序列 code • 存储位置 place

  31. 赋值语句的四元式翻译 S → id := E S.code := E.code || gen( id.place':='E.place ) E → E1 + E2 E.place := newtemp; E.code := E1.code || E2.code || gen(E.place':='E1.place'+'E2.place) E → E1 * E2 E.place := newtemp; E.code := E1.code || E2.code || gen(E.place':='E1.place'*'E2.place)

  32. E → - E1 E.place := newtemp; E.code := E1.code || gen(E.place':=0-'E1.place) E → ( E1 ) E.place:= E1.place; E.code:= E1.code E → id E.place:= id.place; E.code:= ' ' E → num E.place:= num.val;E.code:= ' ' • 注释: || 表示代码序列的连接

  33. 例 6-7:翻译 a:= -c+b*34

  34. 结果:开始符号的属性 S.code • 1) 找出分析树中使用的产生式规则 • 2) 根据产生式的语义规则,代换公式中的各属性 • 3) 反复使用 1) 和 2) 改写公式,最后得到代码生成语句组成的公式 • 组成语句的翻译结果(中间代码序列)

  35. 中间代码的生成过程 S.code => E.code || gen( ‘a:=‘E.place ) /* ‘a’ => id.place */ => E1.code || E2.code || gen( ‘t1:=‘E1.place’+’E2.place ) || gen( ‘a:=t1’ ) /* newtemp => t1 => E.place */ => E11.code || gen( ‘t2:= 0 -’ E11.place ) /* newtemp => t2 => E1.place */

  36. || E21.code || E22.code || gen( ‘t3:=’ E21.place’*’E22.place ) /* newtemp => t3 => E2.place */ || gen( ‘t1:=t2+t3’ ) || gen( ‘a:=t1’ ) => gen( ‘t2:= 0 - c’ ) || gen( ‘t3:=b*34’ ) /* ‘c’ => E11.place */ /* ‘b’ => E21.place */ /* ‘34’ => E22.place */ || gen( ‘t1:=t2+t3’ ) || gen( ‘a:=t1’ ) /* ‘ ’ => E21.code => E22.code */

  37. 表达式翻译中的其他问题 • 运算类型检查 • 利用符号表保存的名字类型 • 类型自动转换 • 填加专用指令 • 临时变量空间的统计 • 了解需求、及时释放

  38. 6.4 控制结构的翻译 • 高级语言的控制结构 • 顺序 begin 语句; 语句 … end • 条件 if_then_else if_then switch case • 循环 while_do do_while for repeat_util • 三地址代码的控制结构 • goto l • if x relop y goto l

  39. S1.code C.code C.true  to C.true  to C.false = S.next  to S1.next = S.begin … S.next S.begin S → while C do S1 的翻译 • 属性设置 布尔式 C • 真出口 true • 假出口 false 语句 S • 入口 begin • 后续段入口 next S.code goto S.begin

  40. S → while C do S1 代码生成的语义规则 C.false := S.next; C.true := newlabel; S.begin := S1.next := newlabel; S.code := gen( S.begin':' ) || C.code || gen( C.true':' ) || S1.code || gen( 'goto'S.begin ) 语义过程 • 新标号的产生 newlabel • 继承属性:C.true C.false S.next • 综合属性:S.code S.begin

  41. C.code  to C.true • to C.false S1.code S2.code C.true C.false  to S1.next = S.next  to S2.next = S.next … S.next S.begin S → if C then S1 else S2的翻译 goto S.next

  42. S → if C then S1 else S2 代码生成的语义规则 C.true := newlabel; C.false := newlabel; S1.next := S2.next := S.next; S.code := C.code || gen( C.true':' ) || S1.code || gen( 'goto' S.next ) || gen( C.false':' ) || S2.code

  43. 简单布尔表达式的翻译 C → E1 relop E2 语义规则 C.code := E1.code || E2.code || gen( 'if' E1.place relop.op E2.place 'goto‘C.true ) || gen( 'goto‘C.false )

  44. 例 6-8:翻译下列语句 while a < b do if c < 5 then x := y else while x > y do z := x + 1;

  45. C.code 生成的三地址代码序列 C1.code L1: if a < b goto L2 goto Lnext L2: if c < 5 goto L3 goto L4 L3: x := y goto L1 L4: L5: if x > y goto L6 goto L1 L6: t1 := x + 1 z := t1 goto L5 goto L1 Lnext: S11.code S1.code S12.code

  46. 控制结构翻译中的其他问题 • 分层结构的记录 • 涉及变量的作用域 • 转移目标的先引用后定义 • 使用回填技术 • 涉及循环语句、条件语句、转移标号

  47. 6.5 属性文法的实现 • 分析 • 属性属于文法符号 • 局限于产生式 • 递归子程序的改进 • 为每个文法符号设置结构或对象类 • 以每个属性为分量 • 每个函数设置一个结构(或对象类)指针

  48. 例 6-9:条件语句的翻译实现 • S 的结构 struct S_Attr { char pCode[MAX]; int iNext; }; • C 的结构 struct C_Attr { char pCode[MAX]; int iFalse; int iTrue; };

  49. 语句 S 的递归函数 void S( struct S_Attr *pS ) { if( lookhead == IF ) { struct C_Attr aC; struct S_Attr aS1; /* if C then S1 */ aC.iTrue = newLabel(); aS1.iNext = aC.iFalse = pS->iNext; match(IF); C( &aC ); match(THEN); S( &aS1 ); sprintf(pS->code, “%sL%d:\n%s\n”, aC.code, aC.iTrue, aS1.code); } … }

  50. 习题 1.把下列语句翻译成三地址代码 while a > 10 if b = 100 then while a < 20 do a := a + b - 1

More Related