编译原理笔记14:自下而上语法分析(1)短语、句柄,规约,移进规约分析器的工作模式

news2024/9/24 1:27:14

目录

    • 基本方法
    • 短语、句柄,规范规约,剪句柄
      • 短语、直接短语和句柄
      • 规范规约(最左规约)
        • 例:
    • 移进-规约
    • 移进规约分析器的工作模式
        • 移进规约分析例:

基本方法

从句子 ω 开始,从左到右扫描 ω,反复用产生式的左部替换产生式的右部、谋求对 ω 的匹配,最终得到文法的开始符号(或,发现错误)(也就是从下往上搞出个树,最后推到根也就是开始符号了)

在分析的过程中,每一步都总是尝试在句型中寻找一个能够被替换为产生式左部的子串。就这样一步步向上去替换,最终变成一个开始符号。

而,由于我们对记号流的扫描是从左到右的,故我们【尝试寻找句型中能够被替换为产生式左部的子串,并不断进行替换】的过程也是从左到右的。这样从记号到开始符号一步进行自下而上分析的逆过程其实就是一个最右推导!

推导的逆过程,就叫做【规约】。最右推导的逆过程,就是最左规约。

在这里插入图片描述

短语、句柄,规范规约,剪句柄

最右推导叫做【规范推导】,因此作为其逆过程的最左规约,也就是【规范规约】了

短语、直接短语和句柄

设 αβδ 是文法 G 的一个句型,若存在 S =*> αAδ , A =+> β,则称 β 是句型 αβδ 相对于 A 的【短语】。若 A→β ,则称 β 是句型 αβδ 相对于产生式 A→β 的【直接短语】。一个句型的最左直接短语被称为【句柄】。

句型,是一个完整的结构,短语则是句型中针对某非终结符的局部。因此,开始符号 S 是句型而不是短语。

短语形成的要素:

  • S 可推导出 A,即 S=*> αAδ ;
  • 从 A 开始经过至少一次推导推出 β,即 A=+> β。

我个人认为(俺寻思):进行规约的一大关键点,是怎么在一堆本质上是字符串的符号流中,试图搞明白 “这到底哪几个连在一块的字符算一个符号啊?这到底几个符号连起来能和哪个产生式的右部匹配上啊?” 的问题。而这里的【短语】、【直接短语】、【句柄】概念,其实就是描述产生式右部的组合及边界的方案——回想自然语言中的 “短语”,自然语言中的短语是指由至少两个单词构成的、有序组合起来共同表达某一个含义的有序单词序列——只有特定的单词以特定的顺序组成序列才能被称为一个短语。那么语法分析中的短语也是一样的:语法分析中的短语是指由至少数个终结符或(和)非终结符构成的、有序组合起来的符号序列,这个序列就是某个产生式的右部,也就可以在规约时被规约为一个产生式的左部。

反映在上面定义的例子中,就是:

  • β 是句型 αβδ 相对于 A 的【短语】,那么 αβδ 就可以经过至少一步规约后规约为 αAδ 。而 αAδ 则能够在经过零或多步规约后,最终规约为开始符号 S;
  • β 是句型 αβδ 相对于产生式 A→β 的【直接短语】,那么 αβδ 就可以在经过一步规约后成为 αAδ ;

在这里插入图片描述

短语,不一定是包含终结符的序列,也可以是单个的非终结符。在整个规约的过程中,句柄会不断变化:毕竟,根据定义,短语只是【从开始符号 S 可以导出(经过零或多步推导,不导也行。。)的非终结符 A 在经过至少一步推导后得出的句型】。那么在下面这个例子中,从开始符号 S 一定是可以经过推导得到非终结符 T2 的,T2 也能在经过一步推导后展开为 F1。那么,F1 就是 T2 的短语(而且是直接短语,而且是最左直接短语,那么这里的 F1 就是 T2 的句柄了)

在这里插入图片描述

  • 短语:以非终结符为根子树中所有从左到右的叶子
  • 直接短语:只有父子关系的树中所有从左到右排列的叶子(树高为2)
  • 句柄:最左边父子关系树中所有从左到右排列的叶子(句柄是唯一的)

规范规约(最左规约)

若 α 是文法 G 的句子且满足下列条件,则称序列 αn, αn-1, …, α0 是一个最左规约:

  1. αn = α
  2. α0 = S( G 的开始符号)
  3. 对任何 i(0 < i <= n),αi-1 是将 αi 中的句柄替换为相应产生式左部的非终结符得到的。

例:

文法:(1)S→aABe (2)A→b (3)A→Abc (4)B→d,对句子 abbcde 的最左规约是:

abbcde <= aAbcde <= aAde <= aABe <= S

上面这个过程,从左往右看是最左规约(称为规范规约),从右往左看就是最右推导了

其实,上面的过程是非常简略的,这里有一些关键的细节需要到后面才能逐渐搞明白。比如,第二步到第三步规约的时候,为什么没有把 aAbcde 规约为 aAAcde?(这是因为如果这样规约就无法继续规约下去了)解决这个问题其实就要用到我们前面博客中说过的 FIRST、FOLLOW 集合以及下推栈。

移进-规约

规约,是用产生式左部的非终结符替换序列中和产生式右部相同的子串的过程。因为规约时对输入序列进行的扫描是从左到右的,所以在规约的过程中每次找的都是序列中的最左直接短语(即句柄)进行规约。

在这个规约的过程中,语法分析程序要做的,就是对输入的符号流中的字符进行扫描,并根据扫描到的字符的情况来对其进行相应的处理:如果可以进行规约则进行规约,如果不能进行规约则进行其他操作。

因为显然,规约不可能是从左到右逐个字符进行处理即可,在实际规约的过程中一定会出现暂时无法进行规约(或者出错)的情况,比如上面那个例子中,排在输入序列第一位的 a 直到最后一步规约中才与句型中的其他符号一起被规约为 E。这说明在规约的过程中,会有“先搁置某些符号,待时机成熟再进行处理”的需求。

这也就是说,我们的语法分析程序需要能够将【暂时不能规约的】字符先按照顺序记录下来。在后面规约的过程中,这个(些)暂时无法被规约的符号要一边等着后面其他可以规约的符号进行规约,一边被语法分析程序监视着——语法分析程序需要能够看情况决定是否要在某次规约中把前面存下的符号加入规约。对字符的存储依然使用栈来进行——用一个栈来存储【将要包含句柄的前缀】,然后在后面不断读取输入字符时,判断已经放在栈中的前缀能否进行规约。

语法分析器对能否规约的判断(什么时候规约、用什么产生式进行规约)也都要依靠一个表来进行,这个表叫做移进规约分析表。

上面这个就是【移进规约】的方法:用栈存储将要包含句柄的输入序列的前缀,用分析表确定【何时栈顶已经形成句柄】以及确定【进行规约要用到的产生式】。

在句柄形成前,要不断将字符从输入序列中移动到栈中。待到栈顶形成句柄时,再将这些符号串规约为一个非终结符。

移进-规约的方法,就是不断地判断扫描过的这部分输入序列的前缀,是否能够被成功地转换为栈中的符号序列。能不能把扫描过的输入序列变成一个文法的【活前缀】(这个词后面会解释)。

土味解说:俺寻思,这语法分析器分析语法,其实就和我们理解人说话差不多:我们说的每句话都包含至少一个单词,有些单词和单词之间是有关联的(也就是多个单词组成一个短语,共同表达一个含义,此时这几个组成短语的单词已经相当于一个整体,需要整体考虑来进行理解)。我们在听其他人说话的时候,我们的耳朵在每个时刻就相当于是一个在读取符号的读写头,追着说话人口中输出的符号流进行读取,并用脑子暂存这个人刚刚说过的某个词,准备与接下来听到的新的词进行关联、整体进行理解。
我们把别人说一半的话先存进脑子等待下文,就是移进(把人家说一半的话移动进入脑子)。
我们完整听完了人家的一段话,可以把这段话进行整体的理解、提取归纳为一个含义,就是规约。

移进规约分析器的工作模式

移进规约分析器的模型和预测分析器非常类似,如下图所示

在这里插入图片描述

其中的 符号状态栈 能构成对存储符号和状态——不止像之前学过的符号栈一样只存储符号,还要存储和这些符号相关的一个状态值。符号和状态在栈中成对存储。

移进-规约分析表 会告诉我们是否能够进行规约,如果规约的话按照哪个产生式进行规约。该表的种类不唯一,根据该分析表的不同,可以将移进规约分析器分为【算符优先分析器】、【LR 分析器】等种类。这些分析器都属于移进规约分析器的不同实现。

移进规约分析器的工作方法,是一步一步进行从格局到格局的转换。这里的格局也是个三元组 (#栈,当前剩余输入#,改变格局的动作)。每到一个新的格局,分析器都要通过查表来确定下一步的动作——该移进还是该规约,如果是规约那该按照哪个产生式进行规约。

语法分析,就是从某个初始格局开始经过一系列的格局变化,最终达到接收格局(成功)或出错格局(发现语法错误)

  • 栈:存放文法符号和状态,并且符号和状态成对出现;
  • 剩余输入:初始格局时为全部序列;接收格局时剩余输入为空;其他格局时是原输入序列的一个后缀。
  • 动作:驱动器根据当前栈和剩余输入来查找分析表确定相应动作,并根据这些动作来改变栈和剩余输入的内容、进入下一格局。能改变格局的动作列举如下:
    • 移进( shift ):将输入序列中的终结符进栈。该动作在当栈顶没有形成句柄时(也就是暂无法规约时)进行;
    • 规约(reduce):当栈顶形成句柄时,根据产生式来将栈顶句柄替换为对应非终结符;
    • 接受(accept):语法分析成功;
    • 报错(error):发现语法错误,调用错误恢复程序。

移进规约分析例:

用移进-规约方法分析 abbcde

在这里插入图片描述

如果把【发生变化了的】句型单独拿出来,从下到上看就是一个最右推导的过程(从下到上就是最左规约了)

在这里插入图片描述

注意

  1. 在最左规约中,句柄总是在栈顶形成的:语法分析器在进行一次规约后,都必须接着移进 0 或多个符号才能在栈顶找到下一个句柄;
  2. 栈中总是含有一个右句型的前缀,且该前缀不包含句柄之后的符号。这个前缀就叫做【活前缀】(在推导的过程中,若每次直接推导均替换句型中最左边的非终结符,则称为最左推导。由最左推导产生的句型被称为左句型。右句型与之对称)。

移进规约分析需要解决的两个关键问题:

  1. 如何判断栈顶是否形成了句柄;
  2. 当形成句柄的时候,如何选择产生式。

说白了,就是要解决:什么时候规约、以及用什么产生式规约的问题

构造分析表,就是构造【识别活前缀的 DFA 】

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

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

相关文章

实现自动驾驶的难点有哪些?

摘要&#xff1a; 这里主要介绍了传感器融合&#xff08;SF&#xff09;对目标方面的几类任务&#xff0c;除目标之外&#xff0c;传感器融合还能做很多其他对环境建模的任务&#xff0c;例如道路特征的描述、占用栅格地图以及可通行区域表示等等。 从车道保持到高阶自动驾驶功…

【从零开始学习JAVA | 第二篇】JAVA综合练习 (1)

目录 前言&#xff1a; 1.买飞机票 2.找质数&#xff1a; 3.开发验证码&#xff1a; 4.数组元素的复制&#xff1a; 5.评委打分&#xff1a; 6.数字加密&#xff1a; 前言&#xff1a; 本篇将起到总结的作用&#xff0c;利用具体案例来带我们复习JAVA的基础内容&#xff…

CountDownLatch源码

介绍 CountDownLatch是依赖AQS完成的线程阻塞和唤醒&#xff0c;利用AQS的共享锁完成锁的多线程获取和释放。 CountDownLatch 使用了共享锁模式。CountDownLatch 使用一个内部类 Sync来实现CountDownLatch的同步控制&#xff0c;而Sync是AQS的一个实现类&#xff0c;它使用AQ…

安装Node,环境配置详细教程及使用

安装Node&#xff0c;环境配置详细教程及使用 一.下载 https://nodejs.org/en/download 一般现在windows电脑都选64位&#xff0c;如果是其他系统或者需要更低的版本可以按照自己的需求进行下载安装&#xff0c;过程都大差不多 二.安装 node.js的安装过程一般都不需要勾选什…

2023/6/21总结

JS 解绑事件 对象.on事件 对象.on事件null 如果是 addEventListener方式必须使用 对象.removeEventListener () 匿名函数无法解绑 mouseover和mouseout会有冒泡效果mouseenter和mouseleave没有冒泡效果 事件委托&#xff1a; 事件委托是利用事件流的特征解决一…

第九章 ShuffleNetv1网络详解

系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网络详解 第七章 MobileNetv2网络详解 第八章 MobileNetv3网络详解 第九章 ShuffleNetv1网络详解 第十章…

【从零开始学习JAVA | 第五篇】This关键字详解

目录 前言&#xff1a; This关键字&#xff1a; 作用&#xff1a; 本质&#xff1a; 总结&#xff1a; 前言&#xff1a; 相信大家在进入JAVA面向对象编程篇章以后&#xff0c;多多少少都见过This关键字&#xff0c;而他的指向很多人总是傻傻搞不清楚&#xff0c;今天我们…

chatgpt赋能python:Python编程语言的词汇量有多少?

Python编程语言的词汇量有多少&#xff1f; Python编程语言是一种广泛使用的高级编程语言&#xff0c;被广泛用于数据科学、机器学习、人工智能、Web开发、游戏开发和其他许多领域。由于Python的简单易学以及丰富的库&#xff0c;越来越多的人开始使用Python编程语言进行编程。…

【MongoDB】四、MongoDB副本集的部署

【MongoDB】四、MongoDB副本集的部署 实验目的实验内容实验步骤实验小结 实验目的 能够通过部署副本集理解副本集机制&#xff0c;从而解决大数据项目中数据丢失的问题 实验内容 环境准备&#xff1a;根据表中的信息完成3台MongoDB服务器的部署&#xff08;XXX是姓名拼音首字母…

C语言指针初阶+进阶(看这一篇就够了)

目录 本章重点 1. 指针是什么 2. 指针和指针类型 3. 野指针 4. 指针运算 5. 指针和数组 6. 二级指针 7. 指针数组 8. 字符指针 9.数组指针 10. 指针数组 11数组传参和指针传参 12. 函数指针 13. 函数指针数组 14. 指向函数指针数组的指针 15. 回调函数 16 指针和数组面试题的解…

【从零开始学习JAVA | 第三篇】类与对象 和 封装

目录 前言&#xff1a; 类与对象&#xff1a; 封装&#xff1a; 总结&#xff1a; 前言&#xff1a; 从本篇开始&#xff0c;我们就要以面向对象编程思想来进行学习了&#xff0c;今天我们学习的内容是类与对象&#xff0c;这是JAVA中的重要知识&#xff0c;让我们一起来进…

docker 项目部署 后端/前端

1.前端部署 2.后端部署 问题一&#xff1a;build出问题 ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 668a7264-5d0b-45a6-b547-fa8fff014bda::g00ukurq2ipxuvrrz8rnpyskp: "/swagger2-demo-0.0.1-SNAPSHOT.jar": …

next.js博客搭建_react-markdown渲染内容(第三步)

文章目录 ⭐前言⭐引入react-markdown&#x1f496; 使用markdown渲染&#x1f496; 文章内容布局&#x1f496; react-syntax-highlighter代码高亮 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本期给大家分享next项目中使用react-markdown渲染内容。 该系列的往期…

考研C语言第八章

结构体定义&#xff0c;初始化&#xff0c;结构体数组 结构体对齐 这个东西看着像数据库里面属性的定义&#xff0c;也像java里面的类的定义 #include <stdio.h> #include <string.h> #include <stdlib.h>struct student{int num;char name[20];char sex;i…

chatgpt赋能python:Python桌面编程:探索图形用户界面

Python桌面编程&#xff1a;探索图形用户界面 Python是一种广受欢迎的高级编程语言&#xff0c;被广泛应用于数据科学、人工智能、Web开发和自动化。但是&#xff0c;随着越来越多的应用程序向图形用户界面&#xff08;GUI&#xff09;转移&#xff0c;Python的桌面编程能力也…

datagrip 连接 phoenix

jar替换完后尽量重启datagrip. 然后重新连接即可. 不重启貌似报错... 效果:

chatgpt赋能python:Python更新界面:让你的应用更美观、更易用

Python更新界面&#xff1a;让你的应用更美观、更易用 Python是一门强大的编程语言&#xff0c;广泛应用于软件开发、数据分析、机器学习等领域。其中&#xff0c;Python的GUI开发能力也非常出色。Python支持多种GUI库&#xff0c;如Tkinter、PyQt、wxPython等&#xff0c;可以…

【C++篇】C++新增的一些基础特性

友情链接&#xff1a;C/C系列系统学习目录 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的…

Python--字典

Python--字典 <font colorblue>一、创建字典<font colorblue>二、访问字典元素<font colorblue>三、字典的增、删、查、改<font colorblue>1、添加元素<font colorblue>2、删除元素<font colorblue>3、查找元素<font colorblue>4、修…

Git——分布式版本控制系统

简介 Git是一个开源的分布式版本控制系统&#xff0c;可以高效的处理从小到很大的项目版本管理。 分类 集中式 SVN&#xff0c;CVS 使用单一的服务器用来管理和存储所有文件的修订版本&#xff1b;协同开发的成员拉取或提交都需连接到这台服务器&#xff1b;如果服务器宕机…