首页 > 其他分享 >day07_编译原理学习

day07_编译原理学习

时间:2024-09-16 20:49:22浏览次数:14  
标签:分析 文法 项目 day07 SLR 编译 归约 LR 原理

第四章 语法分析

LR文法的概述

LR文法的概念

  • LR文法是最大的,可以构造出相应移入-归约语法分析器的文法类

    • L:对输入进行从左到右的扫描
    • R:反向构造出一个最右推导序列
  • LR(k)分析

    • 需要向前查看k个输入符号的LR分析
    • k = 0 和 k = 1 这两种情况具有实践意义,当省略k时,k = 1

LR分析法的基本原理

  • 自底向上分析的关键问题是正确认识句柄
  • 句柄是逐步形成的,用“状态”表示句柄识别的进展程度
    • LR分析器基于这样一些状态来构造自动机进行句柄的识别

LR分析器(自动机)的总体结构

  • LR分析表的结构

  • LR分析器的工作过程
    • 初始化
    • 一般情况下
      • (1)如果ACTION[s_{m}, a_{i}] = sx,那么格局就变为:
      • (2) 如果表示ACTION[s_{m}, a_{i}] = rx表示用第x个产生式A\rightarrow X_{m-(k-1)}...X_{m}进行归约,那么格局变为:
      • (3)如果GOTO[s_[m-k],A]=y,那么格局变为:
      • (4)如果ACTION[s_{m}, a_{i}] = acc,那么分析成功
      • (5)如果ACTION[s_{m}, a_{i}] = err,那么出现语法错误
  • LR分析算法

构造LR分析表

LR(0)分析
  • 右部某位置标有圆点的产生式称为相应文法的一个LR(0)项目(简称为项目)A\rightarrow \alpha_{1}\cdot \alpha_{2}

    • 项目描述了句柄识别的状态

    • 产生式 A\rightarrow \varepsilon只生成一个项目A\rightarrow \cdot

增广文法 
  • 如果G是一个以S为开始符号的文法,则G的增广文法G‘就是在G中加上新开始符号S'和产生式S' -> S而得到的文法

    • 引入这个新的开始产生式的目的是使得文法开始符号仅出现在一个产生式的左边,从而使得分析器只有一个接受状态
  • 文法中的项目
    • 后继项目
      • 同属于一个产生式的项目,但圆点的位置只相差一个符号,则称后者是前者的后继项目
      • A\rightarrow \alpha \cdot X\beta的后继项目是A\rightarrow \alpha X\cdot \beta   
    • “等价”项目
      • 当一个项目中圆点位置后面是一个非终结符时,可能存在“等价”项目
      • 可以把所有等价的项目组成一个项目集(I),称为项目集闭包,每个项目集闭包对应着自动机的一个状态
LR(0)分析表的构造算法
  • CLOSURE()函数

    • 计算给定项目集I的闭包

  • GOTO()函数

    • 返回项目集I对应于文法符号X的后继项目集闭包

  • 构造LR(0)自动机的状态集

    • 规范LR(0)项目族(Canonical LR(0) Collection)

  • LR(0)分析表构造算法

  • LR(0)自动机的形式化定义

    • 文法

    • LR(0) 自动机 

  • LR(0)分析过程中的冲突

    • 表达式文法的LR(0)分析表含有移进/归约冲突

    • 还有一种冲突——归约/归约冲突

    • 如果LR(0)分析表中没有语法分析动作冲突,那么给定的文法就称为LR(0)文法

    • 不是所有CFG都能用LR(0)方法进行分析,也就是说,CFG不总是LR(0)文法

SLR分析

  • SLR分析法的基本思想

  • 表达式文法的SLR分析表

    • 分析表构造算法

      • 如果给定文法的SLR分析表中不存在有冲突的动作,那么该文法称为SLR文法

LR(1)分析

提出
  • SLR只是简单地考察下一个输入符号b是否属于与归约项目A\rightarrow \alpha相关联的FOLLOW(A),但是b\in FOLLOW(A)只是归约\alpha的一个必要条件,而非充分条件(只是合理,但是并不一定正确)

  • 对于产生式A\rightarrow \alpha的归约,在不同的使用位置,A会要求不同的后继符号

  • 在特定位置,A的后继符集合是FOLLOW(A)的子集

规范LR(1)项目
  • 将一般形式为[A\rightarrow \alpha \cdot \beta ,a]的项称为LR(1)项,其中A\rightarrow \alpha \cdot \beta是一个产生式,a是一个终结符(这里将$视作一个特殊的终结符),表示在当前状态下,A后面必须紧跟终结符,称为该项的展望符(lookahead)

    • LR(1)中的1指的是项的第二个分量的长度

    • 在形如[A\rightarrow \alpha \cdot \beta ,a]\beta \neq \varepsilon的项中,展望符a没有任何作用

    • 但是一个形如[A\rightarrow \alpha \cdot ,a]的项在只有在下一个输入符号等于a时才可以按照A\rightarrow \alpha进行归约

      • 这样的a的集合总是FOLLOW(A)的子集,而且它通常是一个真子集

等价LR(1)项目
  • \beta \Rightarrow ^{+}\varepsilon时,此时b = a叫做继承的后继符,否则叫自生的后继符

如果除了展望符外,两个LR(1)项目集是相同的,则称这两个LR(1)项目集是同心的

LR(1)项目集闭包的计算
LR(1)分析表构造算法

LALR分析

LALR(lookahead-LR)分析的基本思想
  • 寻找具有相同核心的LR(1)项集,并将这些项集合并为一个项集。所谓项集的核心就是其第一分量的集合

  • 然后根据合并后得到的项集族构造语法分析表

  • 如果分析表中没有语法分析动作冲突,给定的文法就称为LALR(1)文法,就可以根据该分析表进行语法分析

    • 合并同心项集不会产生移进-归约冲突

    • 合并同心项集后,虽然不会产生冲突,但可能会推迟错误的发现。LALR分析法可能会做多余的归约动作,但绝不会作错误的移进操作

LALR(1)的特点
  • 形式上与LR(1)相同

  • 大小上与LR(0)/SLR相当

  • 分析能力介于SLR和LR(1)二者之间

    • SLR < LALR(1) < LR(1)

二义性文法的LR分析

  • 每个二义性文法都不是LR的

  • 某些类型的二义性文法在语言的描述和实现中很有用

    • 更简短,更自然(消除二义性,  需增加非终结符)

  • 应该保守地使用二义性文法,并且必须在严格控制下使用,因为稍有不慎就会导致语法分析器所识别的语言出现偏差

LR分析中的错误处理

  • 语法错误的检测

    • 当LR分析器在查询分析表并发现一个报错条目时,就检测到了一个语法错误

  • 错误恢复策略

    • 恐慌模式错误恢复

      • 从栈顶向下扫描,直到发现某个状态,它有一个对应于某个非终结符A的GOTO目标,可以认为从这个A推导出的串中包含错误

      • 然后丢弃0个或多个输入符号,直到发现一个可能合法地跟在A之后的符号a为止

      • 之后将s_{i+1}=GOTO(s_{i},A)压入栈中,继续进行正常的语法分析

    • 短语层次错误恢复

      • 检查LR分析表中的每一个报错条目,并根据语言的使用方法来决定程序员所犯的何种错误最有可能引起这个语法错误

      • 然后构造出适当的恢复过程

 

标签:分析,文法,项目,day07,SLR,编译,归约,LR,原理
From: https://blog.csdn.net/m0_74985290/article/details/142289290

相关文章

  • C++从小白到大牛:C++智能指针的使用、原理和分类
    C++从小白到大牛:C++智能指针的使用、原理和分类引言在C++编程中,指针是一个强大但危险的工具。它们允许直接操作内存,但也可能导致内存泄漏、悬空指针等问题。为了解决这些问题,C++引入了智能指针(SmartPointers)的概念。智能指针是一种封装了原始指针的对象,它们自动管理内存的生命周期......
  • ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)
    名词缩写ASID:AddressSpaceID地址空间标识符CD:ContextDescriptor;上下文描述符;CTP:Context-tablepointer上下文表指针EPT:ExtendedPageTable扩展页表GPA:GuestPhyicalAddress客人的实际地址GVA:GuestVirtualAddress访客虚拟地址HPA:HostPhyicalAddress......
  • 【AI大模型】ChatGPT模型原理介绍(下)
    目录......
  • 一个简单的交叉编译riscv的makefile脚本
    为了编写一个使用特定交叉编译工具链(在这个例子中是`riscv64-unknown-linux-gnu-`)来编译`hello.c`的Makefile脚本,你需要设置`CROSS_COMPILE`变量,并在编译命令中使用这个变量来指定交叉编译器的路径。下面是一个简单的Makefile示例:```makefile#定义交叉编译工具链的前缀CROSS_COM......
  • Mysql数据库的原理和应用
    第一章数据库概述一学习环境介绍1.Windows10/11非家庭版内存8g2.Vmwareworkstation16.03.LAMP--LinuxAparchemysqlPHPLNMP--LinuxnginxmysqlPHPWAMP--WindowsAparchemysqlPHPWNMP--WindowsnginxmysqlPHP注意:Windows是非客服端操作系统,而是服务器版......
  • cefsharp.H264.x64.109(88、84、79)可播放视频包免费编译版
    一、下载网址:https://www.nuget.org/packages/CefSharp.H264.x64/109.1.110?_src=templateDownloadpackage(82.59MB)如果是直接下载的cefsharp.h264.x64.109.1.110.nupkg1、用解压缩软件,将这个文件解压缩2、在解压缩目录中(cefshap\cefsharp.h264.x64.109.1.110\cef),再次解压......
  • 并发容器(Map、List、Set)实战及其原理分析
    1.JUC包下的并发容器Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map,大家熟知的这些集合类ArrayList、LinkedList、HashMap这些容器都是非线程安全的。所以,Java先提供了同步容器供用户使用。同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector......
  • GCC安全编译选项
    以CMake为例,给出安全编译选项的定义。关闭RPATH特性。set(CMAKE_SKIP_RPATHTRUE)开启栈保护。set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-fstack-protector-strong")或者set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-fstack-protector-all")开启GOT表保护。set(CM......
  • 《 C++ 修炼全景指南:十 》自平衡的艺术:深入了解 AVL 树的核心原理与实现
    摘要本文深入探讨了AVL树(自平衡二叉搜索树)的概念、特点以及实现细节。我们首先介绍了AVL树的基本原理,并详细分析了其四种旋转操作,包括左旋、右旋、左右双旋和右左双旋,阐述了它们在保持树平衡中的重要作用。接着,本文从头到尾详细描述了AVL树的插入、删除和查找操作,配......
  • springboot原理
    (原创)springboot原理......