编译原理笔记9:语法分析树、语法树、二义性的消除

news2024/10/6 18:22:04

目录

    • 语法分析树
      • 分析树与语言和文法的关系
    • 语法树
    • 二义性及二义性的消除
      • 二义性问题
      • 优先级、结合性:引起二义性的根本原因
        • 【悬空(dangling)else】 问题
      • 二义性的消除
        • 1. 改写二义文法为非二义文法
          • 让我们来搞【悬空 else 】罢!
        • 2. 规定优先级和结合性
        • 3. 修改语言的语法

语法分析树和语法树不是一种东西。习惯上,我们把前者叫做“具体语法树”,其能够体现推导的过程;后者叫做“抽象语法树”,其不体现过程,只关心最后的结果。

语法分析树

语法分析树是语言推导过程的图形化表示方法。这种表示方法反映了语言的实质以及语言的推导过程。

定义:对于 CFG G 的句型,分析树被定义为具有下述性质的一棵树:

  1. 根由开始符号所标记;

  2. 每个叶子由一个终结符、非终结符或 ε 标记;

  3. 每个内部节点都是非终结符;

  4. 若 A 是某节点的内部标记,且 X1、X2…Xn 是该节点从左到右的所有孩子的标记。则:A→X1X2…Xn 是一个产生式。若 A→ε,则标记为 A 的节点可以仅有一个标记为 ε 的孩子。

    以 E => -E => -(E) => -(E+E) => -(id+E) => -(id+id) 为例

在这里插入图片描述

分析树与语言和文法的关系

  • 每一直接推导(每个产生式),对应一仅有父子关系的子树,即产生式左部非终结符“长出”右部的孩子;
  • 分析树的叶子,从左到右构成 CFG G 的一个句型(T、N两掺的串)。若叶子仅由终结符标记(+ 、- 、* 之类的运算符号也算是终结符),则构成一个句子。

推导,有最左推导和最右推导,这两种推导方式在推导过程中的分析树可能不同,但因最终得到的句子是相同的,所以最终的分析树是一样的。

分析树能反映句型的推导过程,也能反映句型的结构。然而实际上,我们往往不关心推导的过程,而只关心推导的结果。因此,我们要对分析树进行改造,得到语法树。语法树中全是终结符,没有非终结符。而且语法树中没有括号

语法树

定义:

对 CFG G 的句型,表达式的语法树被定义为具有下述性质的一棵树:

  1. 根与内部节点由表达式中的操作符标记;
  2. 叶子由表达式中的操作数标记;
  3. 用于改变运算优先级和结合性的括号,被隐含在语法树的结构中。

说白了,语法树这玩意,就一句话:叶子全是操作数,内部全是操作符,树里没有非终结符也不能有括号。

语法树要表达的东西,是操作符(运算)作用于操作数(运算对象)

举俩例子吧:

【例】: -(id+id) 的语法树:

在这里插入图片描述

【例】:-id+id 的语法树:

在这里插入图片描述

显然,我们从上面这两个语法树中,直接就能观察出来它们的运算顺序。

【例】:句型 if C then s1 else s2

在这里插入图片描述

if-then-else 是个终结符,其是一整个操作符。该操作符有三个操作数:条件 C、真分支 s1、假分支 s2

二义性及二义性的消除

二义性问题

二义性问题:一个句子可能对应多于一棵语法树。

【例】: 设文法 G: E → E+E | E*E | (E) | -E | id

则,句子 id+id*id、id+id+id 可能的分析树有:

在这里插入图片描述

在该例中,虽然 id+id+id 的 “+” 的结合性无论左右都不会影响结果。但万一,万一“+”的含义变成了“减法”,那么左结合和右结合就会引起很大的问题了。

我们在这里讲的“二义性”的“义”并非语义——我们现在在学习的内容是“语法分析器”,尚未到需要研究语言背后含义的阶段。

  • “语法”分析的任务,是确定 “E+E” 这么写是否合法;
  • “语义”分析的任务,是确定 “+” 这个符号到底蕴含着什么信息,即,该怎么解释这个符号。

我们现在讲的“二义性”指的是一个句子对应多种分析树。

优先级、结合性:引起二义性的根本原因

二义性的体现,是文法对同一句子有不止一棵分析树。这种问题由【句子产生过程中的某些推导有多于一种选择】引起。悬空 else 问题就可以很好地体现这种【超过一种选择】带来的二义性问题,示例如下。

【悬空(dangling)else】 问题

看下面这么个例子。。

在这里插入图片描述

(其实,我感觉这个其实比较像是“说话大喘气”带来的理解歧义问题。。。)上面的产生式中并没体现出来该咋算分一块,所以两种完全不同的句子结构都是合法的。

二义性的消除

二义性问题是有救的,大概有以下这三种办法:

  1. 将二义文法改成非二义文法;
  2. 规定二义文法中符号的优先级和结合性;
  3. 改变语言的结构或书写方式。

这些办法的核心,其实都是将优先级和结合性说明白。

1. 改写二义文法为非二义文法

核心:把优先级和结合性说明白

既然要说明白,那就不能让一个非终结符可以直接在当次推导中能推出会带来优先级和结合性歧义的东西。(对分析树的一个内部节点,不会有出现在其下面的分支是相同的非终结符的情况。如果有得选,那就有得歧义了。没得选才能确定地一路走到黑)

改写为非二义文法的二义文法大概有下面这几个特点:

  • 需要引入新的终结符,且新引入的非终结符,能够限制每一步推导都只有唯一的选择;
  • 引入新的非终结符后,推到步骤会增多(分析树增高);
  • 越接近 S 的文法符号优先级越低(重要!!);
  • 对于 A → αAβ,若 A 在终结符左侧出现(即终结符在 β 中),则 A 产生式具有左结合性;
  • 在语法树中,越在分析树底下的运算符号越先被计算(即,离开始符号越远的越先算)。

改写的关键步骤:

  1. 引入新的非终结符,增加一个子结构并提高一级优先级;
  2. 若要运算有左结合性,需要让递归非终结符在终结符左边。相对的,递归非终结符在右边则会让运算右结合。

【例】改写下面的二义文法为非二义文法。图右侧是要达成的优先级和结合性

在这里插入图片描述

改写的核心其实就两句话:

  1. 要引入新的优先级,就需要引入新的非终结符,且距离 S 越近的文法符号优先级越低;
  2. 递归非终结符在终结符左边,运算就左结合,反之亦。

所以能够得到非终结符与运算的对应关系(因为不同的运算有不同的优先级,我们想要引入多个优先级就要引入多个新的非终结符。这样每个非终结符就可以负责一个优先级的运算符号,也就是说新的非终结符是与运算有关系的了。因此这里搞出来了“对应关系”四个字)如下:

在这里插入图片描述

优先级由低到高分别是 +、*、-,而距离开始符号越近,优先级越低。因此在这里的排序也可以+*-顺序。每个符号对应一层的非终结符。根据所需要的结合性,则可确定是左递归还是右递归,以确定新的产生式长什么样子

在这里插入图片描述

【例】:规定优先级和结合性,写出改写的非二义文法

在这里插入图片描述

让我们来搞【悬空 else 】罢!

我们已经掌握了一种叫做【改写】的工具,能让我们消除二义性。接下来我们就要用这个工具来尝试搞搞悬空 else 问题!

悬空 else 问题出现的原因是 then 数量多于 else,让 else 有多个可以结合的 then。在二义文法中,由于选哪两个 then、else 配对都可以,故会引起出现二义的情况。在这里,我们规定 else 右结合,即与左边最靠近的 then 结合。

为改写此文法,可以将 S 分为完全匹配(MS)和不完全匹配(UMS)两类。在 MS 中体现 then、else 个数相等即匹配且右结合;在UMS 中 then、else 不匹配,体现 else 右结合。

在这里插入图片描述

例:用改写后的文法写一个条件语句

在这里插入图片描述

经过检查,无法再根据文法写出其他分析树,故已经消除了二义性

2. 规定优先级和结合性

虽然二义文法会导致二义性,但是其并非一无是处。其有两个显著的优点:

  1. 比非二义文法容易理解;
  2. 分析效率高(分析树高度低,直接推导的步骤少)。

在 Yacc 中,我们可以直接指定优先级、结合性而无需自己重写文法。

  %left '+'
  %left '*'
  %right '-'

left 表示左结合,right 表示右结合。越往下的算符优先级越高。

嗯就这么简单。。。

3. 修改语言的语法

我们其实可以把语言本身定义成没有优先级和结合性的。。然后所有的优先、结合都交由括号进行控制,哪个先算就加括号。把一个过程的结束用明确的标志标记出来。

比如在 Ada 中:

if x<3 then 
	if x>0 then 
		x:= 5; 
	end if;
	else x:= -5;
end if;

在 Pascal 中,给表达式加括号:

(a+b)>(c*d)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/669741.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析年轻人的消费动向,小红书盲盒营销怎么玩?

一、ESG营销视角&#xff1a;Z世代年轻价值观的转向 近期&#xff0c;深受品牌方热议的ESG营销是什么呢&#xff1f; ESG 是 Environment&#xff08;环境&#xff09;、Society&#xff08;社会&#xff09; 和 Governance&#xff08;治理&#xff09;的缩写&#xff0c;是…

【openvpn】TAP模式

TAP与TUN模式简介 在OpenVPN中有两种工作模式&#xff0c;一种称为 TUN(tunnel)模式&#xff0c;即通道的意思&#xff1b;另一种是TAP(Terminal Access Point)模式&#xff0c;即一种网络设备或软件虚拟设备的意思。 TUN模式是一种虚拟点对点的网络设备模式。通常用于实现点…

即视角|出海正当时:欧美、东南亚、中东、拉美市场观察

即视角 Insight 共享即构新洞察&#xff0c;共建行业新动能——ZEGO即构科技基于音视频技术领域的多年深耕&#xff0c;综合面向各行业的服务经验&#xff0c;推出【即视角】栏目&#xff0c;发布即构对行业的洞察。欢迎大家探讨论道&#xff0c;共驱前行。 https://v.douyin…

【Note9】

9.PECI&#xff08;Platform Environment Control Interface&#xff09;&#xff1a;peci是 intel提供的私有协议&#xff0c;openbmc是由intel授权的&#xff0c;其他不授权是不能用。硬件上是一根线&#xff0c;不像i2c是2根线 11.1 模式和命令介绍&#xff1a;peci1.1只支…

华为OD机试之拔河比赛(Java源码)

文章目录 拔河比赛题目描述输入描述输出描述示例代码 拔河比赛 题目描述 公司最近准备进行拔河比赛&#xff0c;需要在全部员工中进行挑选。 选拔的规则如下&#xff1a; 按照身高优先、体重次优先的方式准备比赛阵容&#xff1b;规定参赛的队伍派出10名选手。 请实现一个选…

Imagination如何引领更安全的汽车行业?

如果您想购买一款全新的车辆&#xff0c;它很有可能配备数字显示屏&#xff0c;为用户体验提供丰富的驾驶体验&#xff0c;并可自由设置显示。想要更动感的仪表盘&#xff1f;那也没问题&#xff0c;只需改变驾驶主题。亦或是把音乐放在居中位置&#xff0c;同时在另一个屏幕上…

兼容性测试可否提高用户满意度?

兼容性测试可否提高用户满意度? 在信息化时代&#xff0c;软件应用的兼容性一直是一个重要的问题。由于操作系统版本、硬件设备、浏览器等因素的差异&#xff0c;软件在不同环境下运行的稳定性和表现也会不同。因此&#xff0c;如果对软件在不同的环境下进行兼容性测试&#x…

qt信号槽

目录 自定义信号槽 所谓信号槽&#xff0c;实际就是观察者模式 (发布 - 订阅模式)。当某个事件发生之后&#xff0c;比如&#xff0c;按钮检测到自己被点击了一下&#xff0c;它就会发出一个信号&#xff08;signal&#xff09;。这种发出是没有目的的&#xff0c;类似广播。如…

springboot实验室管理系统-计算机毕设 附源码86757

springboot实验室管理系统 摘 要 验室管理系统是将实验室的分析仪器通过计算机网络连起来&#xff0c;采用科学的管理思想和先进的数据库技术&#xff0c;实现以实验室为核心的整体环境的全方位管理。它集用户管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#x…

【历史上的今天】6 月 21 日:第一台存储程序计算机首次运行;XML 之父诞生;IBM 推出 AS/400

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 6 月 21 日&#xff0c;在 23 年前的今天&#xff0c;中国联通公司在香港、纽约成功上市&#xff0c;筹资 56.5 亿美元&#xff0c;进入全球首次股票公开发行史…

LeetCode - #86 分隔链表

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

Cortext-M3系列:M3的底层编程(7)

1、概览 在CM3上编程&#xff0c;既可以使用C也可以使用汇编&#xff0c;keil也支持C&#xff0c;但是大多数人还是会在C与汇编。C与汇编都“尺有所短&#xff0c;寸有所长”&#xff0c;不能互相取代。使用C能开发大型程序&#xff0c;而汇编则用于执行特种任务。 1.1 使用汇…

去中心化金融(DeFi)的发展历史

随着Web3.0的兴起&#xff0c;去中心化金融&#xff08;Decentralized Finance&#xff0c;DeFi&#xff09;正逐渐成为金融领域的热门话题。DeFi旨在通过区块链技术和智能合约&#xff0c;实现无需信任的金融交易和服务&#xff0c;摆脱传统金融中心化的限制。然而&#xff0c…

C# Winform Label 控件

目录 一、概述 二、基本用法 1.控件内容显示 2.控件的外观 3.自定义控件的大小 4.控件的内边距 5.设置文本的固定位置 6.控件的事件 结束 一、概述 Label 控件是 winform 开发中最常用的一个控件&#xff0c;一般用做显示文本&#xff0c;也有时用做打开链接等操作。…

如何解决无法直接启动带有“类库输出类型”的项目

输出类型为类库的项目是编译为 dll 文件的项目&#xff0c;该文件旨在供其他项目使用。它无法直接启动&#xff0c;因为它没有 exe 文件。若要调试此项目&#xff0c;请在此解决方案中添加一个引用库项目的可执行项目。将这个可执行项目设置为启动项目&#xff0c;如下&#xf…

msp430fr2155 在线升级(一)

前言&#xff1a;由于单片机如果不支持USB等方式在线升级&#xff0c;每次升级会设计拆机升级单片机&#xff0c;这对于一个成熟的产品是很鸡肋的。所以记录一下本次研发升级功能的过程以及所需要的问题。 一、升级程序设计 二、内存重新分配 1.芯片原有内存分配 原有内存分…

做电商服务软件(电商ERP),怎么实现与电商平台的数据交互?

电商领域是目前互联网最热门、最活跃的行业之一&#xff0c;随着消费需求的增长和普及化&#xff0c;用户对于商品种类和购物体验的要求也越来越高&#xff0c;精准、高效、快速成为谋求更大商品销量的共同目标。因此&#xff0c;电商服务软件的市场需求正不断增强。 想要开发一…

C++---虚函数(8)

多态 虚函数 虚函数就是在类的成员函数声明前加virtual&#xff0c;该成员函数就变成了虚函数。一旦一个类中有虚函数&#xff0c;编译器就会为该类生成虚函数表。 虚函数表中一个元素记录一个虚函数的地址&#xff0c;使用该类构造对象时&#xff0c;对象前4(8)个字节记录虚…

团队知识库的使用场景有哪些?如何搭建团队知识库?

团队知识库是一种用于共享和管理团队知识和信息的工具。它可以帮助团队成员更好地组织、存储、查找和分享信息&#xff0c;提高工作效率和准确性。以下是团队知识库的使用场景和搭建方法的详细介绍。 一、团队知识库的使用场景 项目管理 团队知识库可以帮助团队成员更好地管…

封神之后,又来超神?南卡OE骨传导开放式耳机有啥新本领

终于到了适合夜跑的温度&#xff0c;我的新跑鞋和专用陪跑运动耳机也都收到了&#xff0c;万事俱备却意外中招“二阳”了。虽然身体情况&#xff0c;短期是不能支持去跑步运动了&#xff0c;但每天戴着新耳机打打王者也还是一样很欢乐的。 反正现在时间很多很闲&#xff0c;我…