属性文法——S属性文法、L属性文法/语法制导定义SDD

属性文法扩展了上下文无关文法,为每个符号分配属性来传递信息。综合属性自底向上计算,继承属性自顶向下。文法开始符号的继承属性作为计算初始值。语义规则指导计算过程,翻译方案将语义动作插入产生式。S-属性文法仅含综合属性,L-属性文法支持不同方向的属性传递。属性计算方法包括树遍历和语法分析同时计算,前者效率较低,后者更高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

属性文法是在上下文无关文法的基础上为每个文法符号(终结符或非终结符)配备若干个相关的“值”(称为属性)。这些属性代表与文法符号相关的信息,例如它的类型、值、代码序列 、符号表内容等等。属性和变量一样,可以进行计算和传递。

属性一般分为两类:

  • 综合属性:用于“自下而上”传递信息。在语法树中,一个结点的综合属性的值由其子结点或其自身的某些属性值确定。
  • 继承属性:用于“自上而下”传递信息。在语法树中,一个结点的继承属性值由该结点的父结点、兄弟结点和其自身的某些属性值确定。

注意:

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

属性传递和计算的过程即是语义处理的过程,其相应的规则就称为语义规则。

语法制导定义(Syntax-Directed Definition, SDD):

  • 每个文法符号和一个属性(attribute)集合相关联
  • 每个产生式和一组语义规则(semantic rules)相关联,这些规则用于计算与该产生式中符号相关联的属性值

翻译方案(Translation Scheme):根据语义处理的先后顺序,把语义动作(程序片段)嵌入到产生式右部的合适位置。

  • 属性的类型(综合/继承)表达了语义信息传递的方向
  • 语义动作的位置表达了语义信息传递的时机(先后顺序)

树遍历的属性计算方法

以某种次序遍历语法树,直至计算出所有的属性。这种方法最简单,适应面最广。

缺点:

  • 必须在语法树建立之后才能使用
  • 效率不高
  • 对每个非终结符号:多次重复计算所有能够计算的继承属性,最后计算所有能够计算的综合属性

一遍扫描的处理方法

在语法分析的同时计算属性值,处理完一个语法单位就执行与之相关的语义处理。

一遍扫描的语法制导翻译:为文法中每个产生式配上一组语义规则,在语法分析的同时执行这些语义规则。

计算语义规则,完成有关语义分析和代码生成动作的时机

  • 自上而下分析中一个产生式匹配输入串成功时
  • 自下而上分析中一个产生式被用于进行归约时

S-属性文法

只含有综合属性的属性文法。

L-属性文法

在这里插入图片描述
L-属性文法支持从上到下、从下到上、从左到右的边。

例题

在这里插入图片描述
首先用S-属性文法处理的结果:

在这里插入图片描述

然后用L-属性文法处理的结果:

在这里插入图片描述

我们可以定义一个综合属性 $num$,表示当前符号所在的子串中已经匹配的括号对数。 对于产生式 $S\rightarrow (L)$,可以设置 $S$ 的综合属性值为 $L$ 的综合属性值。 对于产生式 $S\rightarrow a$,可以设置 $S$ 的综合属性值为 0。 对于产生式 $L\rightarrow L,S$,可以将 $L$ 的综合属性值设置为 $L$ 的综合属性值加上 $S$ 的综合属性值。 对于产生式 $L\rightarrow S$,可以将 $L$ 的综合属性值设置为 $S$ 的综合属性值。 最终,我们可以设置 $S$ 的综合属性值为 $L$ 的综合属性值,表示整个输入串中匹配的括号对数。 下面是对应的 Python 代码实现: ```python class Node: def __init__(self, name): self.name = name self.num = 0 def __str__(self): return self.name def S(node): print(node.num) def L(node): node.num = node.children[0].num + node.children[1].num def L1(node): node.num = node.children[0].num def S1(node): node.num = 0 grammar = { "S": [["(", "L", ")", S]], "L": [["L", ",", "S", L], ["S", L1]], "S": [["a", S1]] } ``` 其中,我们假设每个节点都包含了以下属性: - `name`: 节点的名称。 - `num`: 节点的综合属性值,即子串中已经匹配的括号对数。 - `children`: 节点的子节点列表。 我们可以使用 `Node` 类来表示每个节点。在实现中,我们使用了递归下降分析法来构建语法树,并在语法制导翻译中计算了每个节点的综合属性值。最终,我们在 `S` 函数中输出了整个输入串中匹配的括号对数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花无凋零之时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值