编译原理-学习记录11

ch4.(2)自下而上语法分析(续)

  上回,为了解决移进-规约时的几个问题,引入了几个定义:

  短语

  设有文法G[Z],w=xuy是它的一个句型,如果有: Z ⇒ ∗ x U y Z\mathop\Rightarrow\limits^* xUy ZxUy并且 U ⇒ + u U\mathop\Rightarrow\limits^+u U+u,则称句型xuy中子串u为句型xuy(相对于非终结符号U)的短语

  特别地,如果是 Z ⇒ ∗ x U y Z\mathop\Rightarrow\limits^* xUy ZxUy并且 U ⇒ u U\mathop\Rightarrow u Uu,则称u为句型xuy的直接(简单)短语

  句柄

  句型的最左直接短语称为句柄

  根据定义,短语、直接短语和句柄,都和语法树有关系:

  1、语法树子树的末端结点符号串即是语法树所描述句型(相对于子树的根)的短语
  2、简单子树(只有父子两代)的末端结点符号串即是直接短语
  3、最左简单子树的末端结点符号串即是句柄

  光从文字来看,这样的定义还是太抽象了。这个定义应该对后面的自下而上分析方法很重要,所以不得不看懂。然而这三行看了很久都没看懂,看书也看不懂,最后看了https://icode.blog.csdn.net/article/details/93236597这篇文章才勉强搞懂。现进行举例:

  对于文法G[S]:

S → A B A → A a ∣ b B B → a ∣ S b \begin{aligned}S&\rightarrow AB\\ A&\rightarrow Aa|bB\\ B&\rightarrow a|Sb\end{aligned} SABABAabBaSb

  现打算要求句型baSb的短语、直接短语和句柄。首先使用最右推导的方法,构造出语法树:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUzVjNyd-1606028192783)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122111945679.png)]

  除叶结点单独形成的子树之外,这棵语法树共有4个子树:
  1、B(a)
  2、B(S, b)
  3、A(b, B(a))
  4、S(A(b, B(a)), B(S, b))

  因此,短语共有四个:a、Sb、ba、baSb

  而因为前两棵子树只有父子两代,所以直接短语有两个:a、Sb

  句柄是最左直接短语(位于最左端的简单子树),而两棵子树中,B(a)在B(S, b)的左边,所以句柄应该为a

  在理解定义之后,就开始看LR方法的思想了

LR分析法和LR分析程序

  此类分析法命名为LR,是用于表达“从左至右”的含义

  现在,自上而下语法分析面临的问题,主要就在于这两点:
  1、如何找出当前句型中的句柄
  2、应该将句柄归约到哪一个非终结符号

  在进行详细讨论之前,首先大致浏览程序的总体结构,以展现出LR分析法相对于LL(1)分析法的简洁之处

LR分析程序的逻辑结构

  LR分析程序主要有总控程序和分析表这两个部分

  相比于LL(1),LR多出了一个状态栈,用于存储符号栈中各个符号所对应的状态,而新进栈的符号的状态则是根据栈顶的状态和输入的符号进行查表(分析表)而决定

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tQcNTnGd-1606028192785)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122113959869.png)]

  分析表主要包含:动作部分(ACTION)和状态转换部分(GOTO)。表中使用S表示移进、r表示规约、acc(accept)表示接受、(ACTION部分的)空白表示错处理(而GOTO部分的空白则不是出错处理)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8iUi6SR-1606028192788)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122114433689.png)]

分析表

  尽管LR分析器有好几种类型(常见的有LR(0)、SLR、LR(1)、LALR),但所有LR分析器的总控程序一致,只是分析表不同而已。由此可知,LR分析法的程序是可以通用的,这再次体现出了LR分析法的一个优越之处

LR分析过程简要描述

  LR分析过程主要包括移进、规约、接受和出错四种操作。对过程的简要描述如下:
  1、总控程序在分析的每一步,按照状态栈顶状态q和当前输入符号a,查阅LR分析表,并执行其中ACTION[q,a]和GOTO部分规定的操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRT8eLie-1606028192792)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122114808044.png)]

初始状态

  2、若ACTION [ q i q_i qi a k a_k ak]= S j S_j Sj,则:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9uAqNz43-1606028192794)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122114837421.png)]

  3、若ACTION [ q i q_i qi a k a_k ak]=rj,且第j条产生式为U → \rightarrow x,|x|=m,LR分析表中有GOTO[ q i − m q_{i-m} qim,U]= q t q_t qt,则:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gQbRLKOu-1606028192796)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122114947192.png)]

  4、若ACTION[ q i q_i qi a k a_k ak]=acc,表示接受,不发生变化,分析成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oyLkl7ig-1606028192797)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122115012259.png)]

  5、若ACTION[ q i q_i qi a k a_k ak]=ERROR,表示出错,中止变化

  LR分析过程非常地简单,没有左递归、提取公因子的问题,因此关键在于:如何构造分析表

LR(0)分析表的构造

<!!!>这一段目前还没有很好地理解,所以写出来也是非常地机械的(大多为照搬),之后会考虑对内容进行改进<!!!>

LR分析法的基本原理

  对于由n个符号构成的句柄,如果每识别一个句柄的符号就对应着一个状态,则加上开始状态后,共有n+1个状态

  可以利用打点的方式记录状态,例如,现在有句柄XYZ,则.XYZ表示即将开始得到X,X.YZ表示已经得到X,即将得到YZ,XY.Z表示已经得到XY,即将得到Z,XYZ.表示已经得到XYZ,即将归约

  用LR(0)项目来表示一个句柄的所有识别状态:
  移进项目: U → x . a y U\rightarrow x.ay Ux.ay。点后为终结符号,需要移入栈中
  待约项目: U → x . V y U\rightarrow x.Vy Ux.Vy。点后为非终结符号
  规约项目: U → x . U\rightarrow x. Ux.。点已经到句柄的最后了,已完整地完成
  接受项目: S ′ → S . S'\rightarrow S. SS.。其中,S为开始符号。这里使用了拓广文法,引入了一个新的开始符号S’,和产生式 S ′ → S S'\rightarrow S SS

  即便是在得到完整的产生式右部时,也无法知道能不能规约(信息还是不够),说明不能离开句型谈句柄,即需要句型中的信息,利用历史来帮助判断

  由此引入活前缀:包含了句柄识别到当前时刻的历史,并逐步向后传递,最长活的前缀(可归约前缀)包含了句柄完全被识别的整个历史。这样一来,符号栈中存放的就是活前缀,而符号串和输入串连起来就是句型(从输入串中一个个地移进符号串,并在符号串中规约,所以图中的符号栈和输入串连起来正好就是一个句型):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EbfpfRD6-1606028192799)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122143355391.png)]

  对句柄的识别过程就是对规范句型的活前缀的识别过程,对于这样的识别,可以用确定的有穷自动机来进行

构造识别规范句型活前缀的DFA

  在此处,使用拓广文法:引入一个新的开始符号S’,及对应的产生式 S ′ → S S'\rightarrow S SS

  将所有的产生式的所有状态全部列出,然后根据状态间的转换关系进行相应的连线:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slGyPQob-1606028192800)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122144043425.png)]

  上述方式构造出的是NFA,如果要转换为DFA,则需要进行状态的合并

  首先对空弧的闭包进行状态合并:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSAlek8y-1606028192802)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122144147764.png)]

  合并后,被并入的状态所对应的产生式称作派生项目,反之称为核心项目。例如,在上图的开始状态集中, S ′ → . S S'\rightarrow .S S.S为核心项目,而 S → . a A c B e S\rightarrow .aAcBe S.aAcBe则为派生项目

  随后,再对相同输入所到达的多个状态进行合并:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6PmZ3iw-1606028192803)(C:\Users\蔡三圈\AppData\Roaming\Typora\typora-user-images\image-20201122145444629.png)]

  这样便转换为了DFA

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值