【编译原理复习笔记】属性文法

2024-05-25 04:52

本文主要是介绍【编译原理复习笔记】属性文法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

属性文法

也称为属性翻译文法,由 Knuth 提出,以上下文无关文法为基础
(1)为每个文法符号(终结符与非终结符)配备相关的属性,代表与该文法符号相关的信息
(2)属性文法对于每个产生式都配备了对应的语义规则,标明了语义关系的传递
在这里插入图片描述

属性的分类

综合属性

自下而上的传递信息,根据产生式右部的符号属性计算左部被定义符号的综合属性
在语法树中,即根据子节点的属性和自身的自身属性来计算父节点的综合属性

继承属性

自上而下传递信息,根据右部候选式的符号属性与左部的属性计算右部候选式中符号的继承属性
在这里插入图片描述

属性依赖

对于每个产生式 A → α A \to \alpha Aα都有对应的语义规则,每条规则的形式可以写作:
b,c1,c2 等都为标识符对应的属性
b = f ( c 1 , c 2 , . . . , c k ) b = f(c_1,c_2,...,c_k) b=f(c1,c2,...,ck)
则我们说red:属性 b 依赖于 c1,c2 等
这种依赖又分为我们所提到的综合属性或继承属性
(1)若 b 为综合属性,则 c1,c2 等为产生式右部文法符号的属性
(2)若 b 为右部某个文法符号的继承属性,则 c1,c2 可能为产生式左部或右部任何符号的属性
注意:因为终结符没有子节点,所以终结符只有综合属性,由词法分析器提供

语义规则

(1)对出现在右边的继承属性和左边的综合属性都必须提供相应的计算规则,而且只能使用相应产生式中的文法符号
(2)出现在左边的继承规则和右边的综合属性不由对应产生式的属性计算规则进行计算,而是由其他产生式的属性规则计算或者由相关参数提供

带注释的语法树

在这里插入图片描述
e.g.3*5+4n 利用第一组产生式
对于综合属性,一边自下而上分析构建语法树一边使用语义规则代入
在这里插入图片描述
由此可以得到带注释的语法分析树
对于继承属性,则先构建语法树,然后自上而下填写,对于 addtype,就是在符号表中填写其对应名字,属性对应 addtype 中后项(通常为父节点)所对应的属性
在这里插入图片描述

属性计算

语义规则的计算可以用来:产生代码/在符号表中存放信息/执行动作,blue:对输入串的翻译就是根据语义规则的计算
语法制导翻译法就是将输入串转化为合适的语法树,然后选择适合的语法规则计算属性
基于语法的语义分析方式是多样的,主要有以下三种:
(1)依赖图
(2)树遍历
(3)依赖扫描

依赖图

一颗语法树中的节点的继承属性和综合属性的依赖关系可以由依赖图来描述
若属性 b 依赖于属性 c,则从 c 有一条有向边指向属性 b
根据依赖图,如果一个属性文法不存在属性之间的循环依赖关系(环),则称则称该文法是良定义的
在这里插入图片描述

树遍历

假设语法树已建立,且树中已带有开始符号的继承属性和终结符的综合属性,此后以某种遍历顺序遍历语法树,直到最终所有属性都被计算出来
递归的调用 VisitNode 方法
在这里插入图片描述

一遍扫描

语法树需要反复使用 visitNode,属于多遍扫描,一遍扫描则是根据语法分析的过程同时计算属性值
语义规则的计算时机:
(1)自上而下分析,一个产生式匹配输入串成功时计算语义规则
(2)自下而上分析,一个产生式被归约时计算语义规则
抽象语法树:
建立表达式的抽象语法树
mknode(op,left,right)建立运算符号节点,left 和 right 分别指向左子树和右子树
mkleaf(id,entry)建立标识符节点
mkleaf(num,val)建立数节点
在这里插入图片描述

一遍扫描与自下而上的语法分析器配合工作
在这里插入图片描述

S属性文法

只含有综合属性,使用自下而上的分析器,在原本的状态-符号栈中 增加附加域存放综合属性值
假设 A → X Y Z A \to XYZ AXYZ对应的语义规则为 A . a = f ( X . x , Y . y , Z . z ) A.a = f(X.x,Y.y,Z.z) A.a=f(X.x,Y.y,Z.z)
归约时,将 X、Y、Z 的状态,符号,属性弹出,然后将 A 的状态符号属性压入栈顶

L 属性文法

L 属性文法适合一遍扫描的自上而下分析,通过深度优先地遍历语法树。对于 A → X 1 X 2 . . . X i A \to X_1X_2...X_i AX1X2...Xi,Xi 的继承属性依赖于:
(1)A 的继承属性
(2)Xi 左边符号 X1,X2 等的属性,而不包括右侧
red:S属性文法属于 L 属性文法

翻译模式

语义规则只给出了属性计算的定义,但是没有给出属性计算的先后顺序,可以在属性文法的基础上进一步给出使用顺序,就叫翻译模式
翻译模式:将语义规则与属性用花括号括起来放在合适的位置上,用来表示语法制导翻译的时机
在这里插入图片描述

注意将中缀表达式换成了后缀表达式
(1)当只需要综合属性的时候,将赋值动作放在相应产生式最右侧的末尾
T → T 1 ∗ F T . v a l : = T 1 . v a l × F . v a l T \to T_1*F\\ \\{T.val:=T_1.val\times F.val\\} TT1FT.val:=T1.val×F.val
(2)如果既有综合属性又有继承属性,在建立翻译模式时就必须保证:产生式右边符号的继承属性必须在这个符号之前计算出来
(3)一个动作不能够使用其右边的综合属性
(4)产生式左部的非终结符的综合属性必须等其所有应用的属性被计算出之后才能计算,且需要放在末尾计算

语义动作时机统一

如果能够使所有语义动作都放在产生式的末尾,就可以使每次语义执行的时机统一
方法:
(1)添加一个产生式: M → ϵ M \to \epsilon Mϵ
(2)把嵌入在产生式中间的语义动作用 M 代替,并将这个动作放在产生式 M TO EPSILON 的末尾
在这里插入图片描述

消除翻译模式的左递归

在这里插入图片描述

这里可以理解 R.i 为继承属性,R.s 为综合属性,继承属性必须放在非终结符前,所以 Ri 的语义动作都在 Ri 前,Rs 则放在产生式最后给左部赋值
在这里插入图片描述

这篇关于【编译原理复习笔记】属性文法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000535

相关文章

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、