语法制导的三地址代码生成_编译原理学习笔记(五):属性文法和语法制导翻译...

属性文法和语法制导翻译

一、概述

属性文法,也称为属性翻译文法,以 “上下文无关文法” 为基础,扩充了以下两部分内容:

  • 每个文法符号(终结符或非终结符)有 “值”(属性)
  • 每个产生式有一组属性的语义规则,对属性进行计算和传递

f717ab212a5a4e51fab18d49b25c79ec.png

属性中有两类属性,一种是综合属性,另一种是继承属性。

1.1 综合属性

  • 自下而上传递信息
  • 语法规则:产生式右部确定左部

9ec8b7216966b990a3c22f8556fb8177.png
  • 语法树:子节点确定父节点

f374d0ead600a53eb2ea6ec027092875.png

1.2 继承属性

  • 自上而下传递信息
  • 语法规则:产生式左部确定右部

730e3b4d4535bc1790f5a9e23e90a914.png
  • 语法树:(父节点 + 兄弟节点)确定(子节点)

15cc7b9e9ca81ee17cbbacd6d1529ad0.png

1.3 语义规则

产生式

equation?tex=A%5Crightarrow+%5Calpha 对应的语义规则如下:

equation?tex=b%3A%3Df%28c_1%2Cc_2%2C...%2Cc_k%29

其中共有两种情况:

  • b 是 A 的综合属性,
    equation?tex=c_i 是产生式右边文法符号的属性
  • b 是产生式右边文法符号的继承属性,
    equation?tex=c_i 是 A 或产生式右边文法符号的属性

由此可以如下结论:

  • 终结符只有综合属性,且由词法分析器提供
  • 非终结符可以有综合属性、继承属性
  • 文法开始符号的所有继承属性作为属性计算前的初始值

语义规则功能:

  • 属性计算、静态语义检查
  • 符号表操作、代码生成

0eea4b87f1d748300ad9a746ddcebb59.png

二、带注释的语法树

2.1 S-属性文法

  • 语法树中,一个结点的综合属性的值由其子结点和它本身的属性值确定
  • 使用自底向上的办法在每一个结点处使用语义规则计算综合属性的值
  • 仅使用综合属性的属性文法为 S-属性文法

4823691df8f5d60010458ce8a9ce772f.png
  • 分析过程

81224835a06be0cc8dbd726e148d8b20.png

2.2 L-属性文法

语法树中,结点的继承属性由其父结点、其兄弟结点和其本身的某些属性确定。

  • 继承属性,常用于表示上下文依赖关系

a24dfd27807bd035cae8d9822b39629e.png
  • 文法定义

c49e57b0f57d564891d037f5f23cdd5d.png

三、属性计算

3.1 概述

语义规则的计算功能如下:

  • 产生代码
  • 在符号表中存放信息
  • 给出错误信息
  • 执行任何其它动作

「总结」对输入串的翻译就是根据语义规则进行计算。

3.2 语法制导翻译法

语法制导翻译法:由源程序的语法结构所驱动的处理办法

779f562573b12635542f80f39c898276.png

基于属性文法的处理方法有:

  • 依赖图
  • 树遍历
  • 一遍扫描

3.3 依赖图

「功能」描述一棵语法树中的结点的继承属性和综合属性之间的相互依赖关系

3.3.1 构建算法

4ef766fa4bffbe75168b9eb9c091b46c.png

3.3.2 依赖图举例

77cd9fabffd3eeb89e54e11c7202d107.png
  • 如果一属性文法不存在属性之间的循环依赖关系,则该文法为良定义的
  • 一个依赖图的任何拓扑排序都给出一个语法树中结点的语义规则计算的有效顺序

3.3.3 属性的计算次序

46fbeeaaa8d3ce9f3d0e1473c718e711.png

58985116283615e9e6bcc5b4646d2477.png

3.4 树遍历

「具体方法」通过树遍历的方法计算属性的值

  • 输入时,树中已有开始符号的继承属性和终结符的综合属性
  • 深度优化,从左到右的遍历

10ece3762001bc7555dacde927757c7e.png

3.4.1 树遍历算法

ee2030f30b913139a924d53501d8c3f9.png

3.4.2 树遍历举例

e29f999933946847882804eb5ec68dfb.png

3.5 一遍扫描

  • 在语法分析的同时计算属性值
  • 适用于 S-属性文法 / L-属性文法

3.5.1 抽象语法树

5043a290b0b15b57273c4c2eec1b54a6.png

3.5.2 建立抽象语法树

43194984645d42b45c7ece3862f3892e.png

3.5.3 一遍扫描举例

e07cc4253138b8ef76364c4e7b26e67b.png

89066e4d75dabc7fd05934b1e6dfd418.png
地址代码是编译原理语法分析后的中间语言的一种,这是我刚完成的地址代码生成器,符合的语法规则及其语义规则如下(S→if C then S1 else S2,这条规则没有加,其余都已完成,也许还有bug,欢迎大家给予指正):产生式 语义规则S → id = E S.code = E.code || gen(id.place’:=’E.place)S → if C then S1 C.true = newlabel; C.false = S.next;S1.next = S.next;S.code = C.code || gen(E.true’:’) || S1.codeS → if C then S1 else S2 C.true = newlabel; C.false = newlabel;S1.next = S2.next =S.next;S.code = C.code || gen(E.true’:’) || S1.code ||gen(‘goto’,S.next)|| gen(E.false’:’) || S2.codeS → while C do S1 S.begin = newlabel; C.true = newlabel;C.false = S.next; S1.next = S.begin;S.code = gen(S.begin’:’) || C.code ||gen(E.true’:’) || S1.code || gen(‘goto’S.begin);C → E1 > E2 C.code = E1.code || E2.code ||gen(‘if’E1.place’>’E2.place’goto’C.true) ||gen(‘goto’C.false)C → E1 < E2 C.code = E1.code || E2.code ||gen(‘if’E1.place’<’E2.place’goto’C.true) ||gen(‘goto’C.false)C → E1 = E2 C.code = E1.code || E2.code ||gen(‘if’E1.place’=’E2.place’goto’C.true) ||gen(‘goto’C.false)E → E1 + T E.place = newtemp;E.code = E1.code||T.code||gen(E.place’:=’E1.place’+’T.place)E → E1 - T E.place = newtemp; E.code = E1.code || T.code ||gen(E.place’:=’E1.place’-’T.place)E → T E.place = T.place; E.code = T.codeT → F T.place = F.place; T.code = F.codeT → T1 * F T.place = newtemp;T.code = T1.code || F.code ||gen(T.place’:=’T1.place’*’F.place)T → T1 / F T.place = newtemp; T.code = T1.code || F.code ||gen(T.place’:=’T1.place’/’F.place)F → ( E ) F.place = E
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值