0
点赞
收藏
分享

微信扫一扫

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)


本次笔记内容:

4-8 自底向上的分析概述

4-9 LR分析法概述

4-10 LR0分析

4-11 LR0分析表构造

本节课幻灯片,见于我的 GitHub 仓库:第6讲 语法分析_3.pdf

本节课介绍了​​自底向上的分析​​​,并且举了例子,发现​​移入-归约分析​​​存在问题,因此引出了​​LR分析法​​​,以​​LR(0)分析法​​​为例。在​​LR(0)分析法​​​中,最重要的就是构建​​LR(0)分析表​​​,基于自动机。这个解决方案不错。但是有时,造表时可能出现一些冲突,导致这个​​LR(0)分析法​​​用不了,未来将讲解​​LSR​​​和​​LR(1)​​分析法是如何消解冲突的。


文章目录

  • 自底向上的语法分析
  • 例:移入-规约分析
  • 移入-归约分析的工作过程
  • 移入-归约分析器可采取的4种动作
  • 移入-归约分析中存在的问题
  • LR分析法
  • LR分析法的基本原理
  • LR分析器(自动机)的总体结构
  • LR分析表的结构
  • LR分析表的结构:应用例子
  • LR 分析器的工作过程
  • LR 分析算法
  • LR(0) 分析法
  • LR(0) 项目
  • 增广文法(Augmented Grammar)
  • 文法中得项目
  • 例:LR(0)自动机
  • LR(0)分析表构造算法
  • CLOSURE() 函数
  • GOTO()函数
  • 构造LR(0)自动机的状态集
  • LR(0)分析表构造算法
  • LR(0)自动机的形式化定义
  • LR(0)分析过程中的冲突

自底向上的语法分析

  • 从分析树的​​底部​​​(叶节点)向​​顶部​​(根节点)方向构造分析树
  • 可以看成是​​将输入串w归约为文法开始符号S​​的过程
  • 自​​顶​​​向​​下​​​的语法分析采用​​最左推导​​方式
  • 自​​底​​​向​​上​​​的语法分析采用​​最左归约​​​方式(​​反向​​​构造​​最右推导​​)
  • 自底向上语法分析的通用框架:移入-归约分析(Shift-Reduce Parsing)

例:移入-规约分析

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法

逐步分析如图右侧“动作”,很明确;个人理解是从闻法得右侧向左推导。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编程语言_02

注意到,每一个蓝色虚线划分的区域中,​​栈+剩余输入​​的内容,总是构成一个相同的“规范句型”。

移入-归约分析的工作过程

在对​​输入​​​串的一次从左到右扫描过程中,语法分析器将零个或多个输入符号​​移入​​​到​​栈​​​的顶端,直到它可以对栈顶的一个文法符号串β进行​​归约​​为止;

  • 然后,它将β​​归约​​为某个产生式的左部;
  • 语法分析器不断地重复这个循环,直到它检测到一个语法​​错误​​​,或者栈中包含了开始符号且输入缓冲区为空(当进入这样的格局时,语法分析器停止运行,并宣称​​成功​​完成了语法分析)为止。

移入-归约分析器可采取的4种动作

  • 移入:将下一个输入符号移到栈的顶端;
  • 归约:被归约的符号串的​​右端​​​必然处于栈顶。语法分析器在栈中确定这个串的​​左端​​,并决定用哪个非终结符来替换这个串;
  • 接收:宣布语法分析过程成功完成;
  • 报错:发现一个语法错误,并调用错误恢复子例程。

移入-归约分析中存在的问题

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_03

如图,对一个语句 ​​var iA , iB : real​​​ 进行分析,最后​​剩余输入中已经没有任何符号了,而栈中并没有归约出文法的开始符号<S>,因此分析失败。​

但是,这个文法其实是合法的句子,那么问题出在:​错误地识别了句柄,如上图;应该如下图一样进行分析。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法_04

那么,如何避免这种错误?正确识别句柄呢?

将在接下来地​​LR分析​​技术中详细介绍。

LR分析法

  • LR文法(Knuth, 1963) 是最大的、可以构造出相应​​移入-归约语法分析器​​的文法类
  • L: 对输入进行从​​左​​到右的扫描
  • R: 反向构造出一个最​​右​​推导序列
  • LR(k)分析
  • 需要向前查看k个输入符号的LR分析
  • ​k = 0 和 k = 1 这两种情况具有实践意义;当省略(k)时,表示k =1​

LR分析法的基本原理

自底向上分析的关键问题是什么?

  • 如何正确地识别句柄

句柄是逐步形成的,用“状态”表示句柄识别的进展程度。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编程语言_05

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

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法_06

与移入规约不同的是,LR分析器还包含一个与符号栈平行的状态栈。

LR分析表的结构

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编译原理_07

  • sn表示,将符号a、状态n压入栈;
  • rn表示,用第n个产生式进行归约(r是reduce的缩写)
  • GOTO中表示,在某一状态,遇到某一非终结符,进入到后继状态。
  • ​acc​​是成功接收的意思。

LR分析表的结构:应用例子

还是上面的分析表,现在输入 ​​b a b​​​ ;下面的表格将阐述​​栈与剩余输入的快照​​(分析过程)。

状态栈

符号栈

剩余输入

0

$

bab$

0号状态遇到b,移入动作,入栈。

状态栈

符号栈

剩余输入

04

$b

ab$

查表得,4号状态与b,对应动作​​r3​​​,用第3个产生式进行归约,也就是说​​b出栈​​​,​​B进栈​​。

状态栈

符号栈

剩余输入

0

$B

ab$

差表得,0号状态与B,对应GOTO 2,则2号状态进栈。

状态栈

符号栈

剩余输入

02

$B

ab$

状态栈

符号栈

剩余输入

023

$Ba

b$

状态栈

符号栈

剩余输入

0234

$Bab

$

状态栈

符号栈

剩余输入

023

$BaB

$

状态栈

符号栈

剩余输入

0236

$BaB

$

状态栈

符号栈

剩余输入

02

$BB

$

状态栈

符号栈

剩余输入

025

$BB

$

状态栈

符号栈

剩余输入

0

$S

$

状态栈

符号栈

剩余输入

01

$S

$

​1$对应的acc代表成功接收。​

LR 分析器的工作过程

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法_08

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_自动机_09

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编程语言_10

LR 分析算法

  • 输入:串w和LR语法分析表,该表描述了文法G的ACTION函数和GOTO函数。
  • 输出:如果w在L(G)中,则输出w的自底向上语法分析过程中的归约步骤;否则给出一个错误指示。
  • 方法:初始时,语法分析器栈中的内容为初始状态s0,输入缓冲区中的内容为w$。然后,语法分析器执行下面的程序。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_11

可以看出,LR分析算法较为简单,重点在于如何构造​​LR分析表​​,包括四种,将在后面分别进行介绍:

  • LR(0)分析
  • SLR分析
  • LR(1)分析
  • LALR分析

LR(0) 分析法

LR(0) 项目

右部某位置标有圆点的产生式称为相应文法的一个​​LR(0)​​项目(简称为项目)。

A → a 1 ⋅ a 2 A \rightarrow a_1 \cdot a_2 A→a1​⋅a2​

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编译原理_12

项目描述了​​句柄识别的状态​​;右侧有k个符号,则有k+1个项目。

增广文法(Augmented Grammar)

如果G是一个以S为开始符号的文法,则G的​​增广文法​​G’ 就是在G中加上新开始符号S’ 和产生式S’ → S而得到的文法。(我个人理解就是一句话,在开头)

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_13

引入这个新的开始产生式的目的是使得​​文法开始符号仅出现在一个产生式的左边​​​,从而使得​​分析器只有一个接受状态​​。

文法中得项目

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_14

后继项目(Successive Item):

  • 同属于一个产生式的项目,但圆点的位置只相差一个符号,则称后者是前者的后继项目;
  • A→α· Xβ的后继项目是A→αX·β

上面一共有15个项目,是否会有项目是等价的呢?

  • (0)和(2)是等价的;
  • (3)和(7)/(11)是等价的;
  • (5)和(13)是等价的。

当项目中圆点后面的符号是非终结符时,其存在等价项目。

可以把等价的项目组成一个​​项目集( I )​​​,称为​​项目集闭包​​​(Closure of Item Sets),每个项目集闭包对应着​​自动机​​​的一个​​状态​​。

例:LR(0)自动机

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编译原理_15

首先构造​​自动机​​,随后根据自动机画LR(0)分析表。

LR(0)分析表构造算法

如何实现上文的自动机?

首先定义两个函数。

CLOSURE() 函数

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法_16

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_自动机_17

GOTO()函数

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_自动机_18

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

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_自动机_19

LR(0)分析表构造算法

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_LR分析法_20

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

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_编程语言_21

LR(0)分析的基本原理,就是根据给定的文法,来构造对应的自动机M:

  • M的状态集就是​​C​​,符号表就是非终结符和终结符集合的并集,转换函数就是GOTO函数;
  • M的初始状态​​I0​​就是文法的初始项目的项目集闭包;
  • M的终止状态​​F​​就是文法的接收项目的项目集闭包。

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

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_自动机_22

如图,是一个描述​​算术表达式的文法​​。

这里状态2、9存在冲突现象:存在​​移进/归约冲突​​。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_23

此外,还有​​归约/归约​​冲突。

【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)_归约_24

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

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

如何消解冲突?

  • 在后面将介绍​​LSR​​​和​​LR(1)​​分析法是如何消解冲突的。


举报

相关推荐

0 条评论