编译原理(三)语法分析:8.自下而上语法分析


【编译原理博客列表】》》》》》》


一、自下而上分析

自上而下分析的方法是产生语言的自然过程。但是对于分析源程序来讲,自下而上分析的方法更自然,因为语法分析处理的对象一开始都是终结符组成的串,而不是文法的开始符号。
同时,自下而上分析中最一般的方法,LR方法的能力比自上而下分析的LL方法要强,从而使得LR分析成为最为实用的语法分析方法。

1.短语

在这里插入图片描述
方法:画出分析树,根据分析树分析

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

例:文法:E→E+T|TT→T*F|FF→id
句型:id1+id2*id3

分析树:
在这里插入图片描述

短语:
id1+id2*id3	(E1)
id2*id3		(T1)
id1			(E2, T2, F1)
id2			(T3, F3)
id3			(F2)

直接短语:
id1			(F1)
id2			(F3)
id3			(F2)

句柄:id1	(F1)

PS:
问题:id1+id2是句型id1+id2*id3的短语吗?
答案:不是。
为什么?
① 没有一个E的子树,它的全部叶子是id1+id2;或者②找不到某个E,使得 E=*>E*id3E=+>id1+id2

2.最左归约

最左归约的逆过程是一个最右推导,分别称最右推导和最左归约为规范推导和规范归约。

替换为相应产生式左部非终结符,归约符号是<=

在这里插入图片描述

3.移进-归约分析器

(1)工作模式

在这里插入图片描述

  • 工作方法:放幻灯,每个幻灯片是一个格局。
  • 格局:(#栈中内容当前剩余输入#改变格局的动作
  • 改变格局的动作:
    • 移进(shift):输入序列中的终结符进栈。(匹配终结符)
    • 归约(reduce):将栈顶句柄替换为对应非终结符(最左归约)
    • 接受(accept):宣告分析成功
    • 报错(error):发现语法错误,调用错误恢复例程

PS:栈中保留的总是一个右句型的前缀(加上若干终结符形成句型),称为活前缀

例3.27 用移进-归约方法分析abbcdeabbcde<=aAbcde<=aAde<=aABe<=S

在这里插入图片描述

二、构造SLR(1)分析器

1.定义3.17 项目

一个LR(0)项目(简称项目)是这样一个产生式,在它右部的某个位置有一个点“.”。对于A→ε,它仅有一个项目A→.。

E→E-T|T T→T*F|F F→-F|id 的全部LR(0)项目:

E→.E-T  E→E.-T  E→E-.T  E→E-T.
E→.T    E→T.
T→.T*F  T→T.*F  T→T*.F  T→T*F.
T→.F    T→F.
F→.-F   F→-.F   F→-F.
F→.id   F→id. 

项目A→α.β显示了分析过程中看到(移进)了产生式的多少。

  • β不为空的项目称为可移进项目
  • β为空的项目称为可归约项目

2.拓广文法与识别活前缀的DFA

(1)拓广文法G’

G' = G∪{S'→S}
其中:

  • S'→.S是识别S的初态,
  • S'→S.是识别S的终态。
  • 目的是使最终构造的DFA状态集中具有唯一的初态和终态。

例:文法G:E→E-T|TT→T*F|FF→-F|id

拓广文法:G' = G∪{E'→E}
唯一初态与终态:E'→.EE'→E.

(2)NFA(项目)→DFA(项目集)

词法分析器-“子集法” :

  • ① ε_闭包(I):从状态集I不经任何字符能到达的状态全体;
  • ② smove(I,a):所有从I经字符a能直接到达的状态全体。

类似的两个过程:

  • closure(I):从项目集I不经任何文法符号到达的项目全体
  • goto(I,x):所有从I经文法符号x能直接到达的项目全体

定义3.20
项目[S'→.S]和所有“.”不在产生式右部最左边的项目称为核心项目(kernel items),其它“.”产生式右部最左边的项目(不包括[S’→.S])称为非核心项目(nonkernel items)。

(3)构造DFA:

  • 计算DFA的初态,I0=closure({S'→.S})
  • 计算所有状态的所有状态转移,即考察每个未标记状态Ii=closure(goto(Ii,x)))

例:G : S→ABA→aAb |abB→c |Bc

拓广文法 G' = G∪{S'→S},构造的 DFA 如下,其中 I0 为初态,I1 为终态。

在这里插入图片描述
在这里插入图片描述

(4)项目集中的冲突

冲突:

  • 移进/归约冲突:A→β1.β2B→β1.β1.有东西和没东西】:既可移进又可归约
  • 归约/归约冲突:A→α.B→α.α.都没东西】:均可指导下一步分析

解决方法:简单向前看一个终结符:
移进/归约冲突:若FIRST(β2)∩FOLLOW(B)=Φ,冲突可解决
归约/归约冲突:若FOLLOW(A)∩FOLLOW(B)=Φ,冲突可解决
【移进是看输入文法序列中的下一个字符,即项目.右部的字符,所以是FIRST(β2);归约是舍弃当前栈中的非终结符,即项目左部。】
【交集为空,表示下一步展开是唯一的,所以冲突可解决】

发布了411 篇原创文章 · 获赞 144 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/sandalphon4869/article/details/103814231