编译原理系列之六 自底向上的LR分析法(1)-LR(0)分析法

LR(0)分析法

一、基本概念

  1. 拓广文法:

    对于文法 G = (VN, VT, P , S ) , 增加如下产生式:S’->S ,其中, S’ ∈ VN∪ VT , 得到 G 的拓广文法,G’ = (VN ’, VT, P ’ , S’ )

    其实就是增加了一条右部为开始符号的产生式,就变成了拓广文法

  2. 可归前缀:

    采取归约过程前符号栈中的内容,称做可归前缀。
    这种前缀包含句柄且不包含句柄之后的任何符号;

  3. 活前缀

    对于文法 G = (VN, VT, P , S ) , 设 S’ 是其拓广文法的开始符号(即有产生式 S’-> S), 且α,β∈(VN∪VT)* , ω∈VT*。
    若 S’ =*=>α A ω 且 A ->β, 即 β 为句柄,则 αβ 的任何前缀 γ 都是文法 G 的活前缀。
    注:由于 S’ =*=>S’ 且 S’ -> S, 故 S 是 G 的活前缀 。

    也就是说可归前缀的所有前缀(包括可归前缀)都是活前缀。

    例:文法 G[S] :
    (1) S -> AB
    (2) A -> aA
    (3) A -> ε
    (4) B -> b
    (5) B -> bB
    句子 aaab 是一个句型,其唯一的句柄为:ε (aaaεb); 活前缀有:ε,a,aa,aaa。

    当前分析了的部分(符号栈中的符号)为规范句型的活前缀,表示当前分析了的部分是某规范句型的正确部分。

  4. LR(0)项目 :

    在文法G中每个产生式的右部适当位置添加一个圆点构成项目。

    每个项目的含义是:欲用改产生式归约时,圆点前面的部分为已经识别了的句柄部分,圆点后面的部分为期望的后缀部分。

    分类:

    移进项目: 形如 A -> α• aβ,对应移进状态,把a移进符号栈。
    待约项目: 形如 A -> α • Bβ,对应待约状态,需要等待分析完非终结符B的串再继续分析A的右部。
    归约项目: 形如 A -> α •,句柄已形成,可以归约。
    接受项目: 形如 S’ -> S •。
    初始项目: 形如 S’ -> • S。
    其中a∈VT , α,β∈(VN∪VT)*, A,B∈VT
    后继项目: 表示同属于一个产生式的项目,但是圆点的位置仅相差一个文法符号,则称后者为前者的后继项目。

    例:对于产生式S -> aAcBe,它有6个项目:
    S -> ·aAcBe
    S -> a·AcBe
    S -> aA·cBe
    S -> aAc·Be
    S -> aAcB·e
    S -> aAcBe·

二、LR(0) 有限状态机的构造方法

1.用闭包函数(CLOSURE)来求DFA一个状态的项目集:

CLOSURE(I)是这样定义的:
首先I的项目都属于CLOSURE(I);
如果A->α• Bβ,则左部为B的每个产生式中的形如B->·γ项目,也属于CLOSURE(I);

例子:已知文法G[E]如下:
(1) E -> E+T
(2) E -> T
(3) T ->( E )
(4) T -> d

可以直到它的拓广文法G’ [E’]为 :
(0) E’ -> E
(1) E -> E+T
(2) E -> T
(3) T -> ( E )
(4) T -> d

令I0 = CLOSURE({E’->.E})

则I0 = {
E’ -> • E,
E -> • E+T,
E -> • T,
T -> •( E ),
T -> • d
}

2.LR(0) FSM 的状态转移函数

GO (I,X) = CLOSURE(J)
其中,I为LR(0) FSM 的状态(闭包的项目集),X为文法符号, J={ A -> αX•β | A -> α• Xβ∈I} ;
表示对于一个状态项目集中的一个项目A -> α• Xβ,在下一个输入字符是X的情况下,一定到另一个新状态 A -> αX•β。

3.LR(0) 有限状态机的构造

从 LR(0) FSM 的初态出发 ,先求出初态项目集的闭包(CLOSURE({S’->.S})),然后应用上述转移函数,通过项目分析每种输入字符下的状态转移,若为新状态,则就求出新状态下的项目集的闭包,级可逐步构造出完整的 LR(0) FSM。

LR(0) FSM 的构造举例
给定文法G[E]:
(1) E -> E+T
(2) E -> T
(3) T -> ( E )
(4) T -> d

构造LR(0) FSM
① G[E]的拓广文法,得到G’ [E’]:
(0) E’ -> E
(1) E -> E+T
(2) E -> T
(3) T -> ( E )
(4) T -> d

②构造G’[E’] 的 LR(0) FSM

 

2869373-16bab55cf10501de.png

LR(0) FSM

三、LR(0) 分析法

1.LR(0) 文法定义

文法 G 是 LR(0) 文法,当且仅当它的LR(0)FSM中的每个状态都满足:
①不同时含有移进项目和归约项目,即不存在移进-归约冲突。
②不含有两个以上归约项目,即不存在归约-归约冲突。

2.LR(0)分析表的构造

ACTION 表项和 GOTO表项可按如下方法构造:

  • 若项目A ->α • aβ属于 Ik 且 GO (Ik, a)= Ij, 期望字符a 为终结符,则置ACTION[k, a] =sj (j表示新状态Ij);

  • 若项目A ->α • Aβ属于 Ik,且GO (Ik, A)= Ij,期望字符 A为非终结符,则置GOTO(k, A)=j (j表示文法中第j个产生式);

  • 若项目A ->α •属于Ik, 那么对任何终结符a, 置ACTION[k, a]=rj;其中,假定A->α为文法G 的第j个产生式;

  • 若项目S’ ->S • 属于Ik, 则置ACTION[k, #]为“acc”;

  • 分析表中凡不能用上述规则填入信息的空白格均置上“出错标志”

    翻译一下:

    1. 如果圆点不在项目k最后且圆点后的期待字符a为终结符,则ACTION[k, a] =sj (j表示新状态Ij);
    2. 如果圆点不在项目k最后且圆点后的期待字符A为非终结符,则GOTO(k, A)=j (j表示文法中第j个产生式);
    3. 如果圆点在项目k最后且k不是S’ ->S,那么对所有终结符a,ACTION[k, a]=rj (j表示文法中第j个产生式);
    4. 如果圆点在项目k最后且k是S’ ->S,则ACTION[k, #]为“acc”;

例子:

考虑文法G[S] :
S → (S) | a
相应的LR(0) FSM如下,构造其LR(0)分析表。

2869373-24792d5abfee9bbe.png

LR(0) FSM

从I0看,S‘->·S,期望字符是非终结符S,根据上面的规则2,得到GOTO(0,S)=1;
S‘->·(S),期望字符是终结符(,根据上面的规则1,得到ACTION(0,()=S2;
从I3看,S->a·,根据规则3,置ACTION[3, a]为r2;
从I1看,S‘->S·,根据规则4,置ACTION[1, #]为“acc”;

2869373-ae315fcdb75b399c.png

LR(0)分析表

3.LR(0) 分析流程

设输入串为w,ip指向输入串w的首符号a,i指向符号栈顶;状态栈的初始栈顶为0,符号栈初始栈顶为#。

算法流程图为:

2869373-f4701ccabe0b0297.png

LR(0) 算法流程图

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在规范规约的过程中,一方面记住已移进和规约出的整个符号串,即记住“历史”,另一方面根据所用的产生式推测未来可能碰到的输入符号,即对未来进行“展望”。当一串貌似句柄的符号串呈现于分析栈的顶端时,我们希望能够根据记载的“历史”和“展望”以及“现实”的输入符号等三个方面的材料,来确定栈顶的符号串是否构成相对某一产生式的句柄。 2.LR分析器实质上是一个带先进后出存储器(栈)的确定有限状态自动机。 3.LR分析器的每一步工作是由栈顶状态和现行输入符号所唯一决定的。 4.为清晰说明LR分析器实现原理和模型: LR分析器的核心部分是一张分析表。这张分析表包括两个部分,一是“动作”(ACTION)表,另一是“状态转换”(GOTO)表。他们都是二维数组。ACTION(s,a)规定了当状态s面临输入符号a时应采取什么动作。GOTO(s,X)规定了状态s面对文法符号X(终结符或非终结符)时下一状态是什么。显然,GOTO(s,X)定义了一个以文法符号为字母表的DFA。 每一项ACTION(s,a)所规定的动作不外是下述四种可能之一: (1)移进 把(s,a)的下一个转态s’ = GOTO(s,X)和输入符号a推进栈,下一输入符号变成现行输入符号。 (2)规约 指用某一产生式A→β 进行规约。假若β的长度为r,规约的动作是A,去除栈顶的r个项,使状态Sm-r 变成栈顶状态,然后把(Sm-r,A)的下一状态s’ = GOTO(Sm-r,A)和文法符号A推进栈。规约动作不改变现行输入符号。执行规约动作意味着β(= Xm-r+1…Xm)已呈现于栈顶而且是一个相对于A的句柄。 (3)接受 宣布分析成功,停止分析器的工作。 (4)报错 发现源程序含有错误,调用出错处理程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值