编绎原理 - 构造LR(0)分析表与输入串分析过程表

本文详细介绍了LR(0)文法的概念、如何拓展文法并构造识别活前缀的DFA,以及如何构建LR(0)分析表。通过实例演示了分析过程,包括处理移进-规约冲突和规约-规约冲突,最后提供了一个练习题供读者实践。
摘要由CSDN通过智能技术生成

目录

一、 什么是LR(0)文法

1、概念

2、解释

二、实现步骤

1、拓广文法,加入一个用于产生开始符号的产生式,并从0开始编号

2、构造识别活前缀的DFA

(1)第一个项目集(或状态)

①项目集解释

(2)完整活前缀的DFA如下

​编辑

解释

例如

3、构造LR(0)分析表

(1)说明

(2)LR(0)分析表如下

​编辑

4、对于输入串acd#的分析过程

解释

步骤1

步骤2

步骤3

步骤4

步骤5

步骤6

步骤7

三、练习

1、拓广文法并编号

2、构造活前缀的DFA

3、构造LR(0)分析表

4、对于输入串abcde的分析过程


建议

可以使用PixPin截图软件将多个截图固定在屏幕上方,方便后面边看边理解

链接:https://pixpinapp.com/

一、 什么是LR(0)文法

1、概念

若一个文法 G 的拓广文法 G’ 的识别活前缀的自动机中的每个状态(项目集)均不存在下述情况:

  1. 既有移进项目又有规约项目(移进-规约冲突);
  2. 含有多个规约项目(规约-规约冲突),

则称 G 为一个 LR(0) 文法

2、解释

项目分类如下

基本项目:圆点在最左边                  例:E→ •S

移进项目:圆点后边是终结符           例:E→•aS

待约项目:圆点后边是非终结符        例:E→a•S

规约项目:圆点在最右边                   例:E→aS•

二、实现步骤

例:已知文法

G[E]: E→aA

          A→cA

          A→d

1、拓广文法,加入一个用于产生开始符号的产生式,并从0开始编号

      0    S→E                   产生E的符号随意(除E以外)

      1    E→aA

      2    A→cA

      3    A→d

2、构造识别活前缀的DFA

(1)第一个项目集(或状态)

①项目集解释

第0个产生式出发构造基本项,若圆点右侧有非终结符,则写出该非终结符的基本项

(2)完整活前缀的DFA如下

解释

接受一个符号,产生一个新的状态(保留的为可接受该符号的项目),且圆点向前进一位。

同样,若圆点后为非终结符需写出该非终结符的基本项。

直到出现规约状态(圆点在最右侧)

检查DFA是否正确,可通过判断规约项的个数是否等于拓广后产生式的个数

例如

I2中A→•cA接受c进入到I4状态,圆点向前一位:A→c•A

圆点后为非终结符A,写出A的基本项,即A→•cA   A→•d

之后写出I4接受符号后产生的状态,直到出现规约项(即I5、I6)

其中I4接受c还是它本身,不用再写新状态,指向它本身即可

3、构造LR(0)分析表

由上图DFA可得,同一个项目集不存在移进与规约,规约与guiyue

(1)说明

①状态中写DFA的几个状态

ACTION中写终结符,包括#

ACTION中Sn ,代表接受符号后转向哪个状态,n代表第n个状态

ACTION中Rn,代表规约成第n个产生式,且Rn占整个ACTION

⑤ACTION中产生开始符号的规约项,在#处写acc

GOTO中写非终结符,不包括新加进去的那个,即S

GOTO中转向哪个状态直接写状态号即可

(2)LR(0)分析表如下

4、对于输入串acd#的分析过程

说明:转向,则余留输入串分析出一个,余留输入串栈-1,而符号栈+1

           规约,则余留输入串不变,符号栈进行规约

步骤状态栈符号栈余留输入串栈ACTIONGOTO
10#acd#2
202#acd#4
3024#acd#6
40246#acd#35
50245#acA#23
6023#aA#11
701#E#acc

解释

步骤1

状态栈:0

符号栈:#

余留输入串栈:acd#

ACTION:0接受a,转向2状态

分析出c

步骤2

状态栈:0转向2,为02

符号栈:上步分析出a,即符号栈为:#a

余留输入串栈:a被分析,出栈,剩余cd#

ACTION:2接受c,转向4状态

分析出c

步骤3

状态栈:2转向4,为024

符号栈: 上步分析出c,即符号栈为#ac

余留输入串栈:c被分析,出栈,剩余#d

ACTION:4接受d,转向6

分析出d

步骤4

状态栈:4转向6,为0246

符号栈:上步分析出d,即符号栈为#acd

余留输入串栈:d被分析,出栈,剩余#

ACTION:6接受#,规约为产生式3

GOTO:

3产生式如下: A→d

d规约成A

len(3产生式)=|d|=1

出栈1个状态,即状态栈此时为024

GOTO[状态,规约成的非终结符

=GOTO[4,A]=5     4状态接受A为5状态

步骤5

状态栈:上步出栈一个状态,进入状态5,即0245

符号栈:d规约成A,即符号栈为#acA

余留输入串栈:不变,#

ACTION:5接受#规约为2产生式

GOTO:

2产生式如下:A→cA

cA规约成A

len(2产生式)=|cA|=2

出栈2个状态,及状态此时为02

GOTO[状态,规约成的非终结符]

=GOTO[2,A]=3

步骤6

状态栈:上步出栈2个状态,进入状态3,即023

符号栈:cA规约成A,即符号栈为#aA

余留输入串栈:不变,#

ACTION:3接受#规约成为1

GOTO:

1产生式如下:E→aA

aA规约成E

len(1产生式)=|aA|=2

出栈2个状态,及状态此时为0

GOTO[状态,规约成的非终结符]

=GOTO[0,E]=1

步骤7

状态栈:上步出栈2个状态,进入1状态,即01

符号栈:aA规约成E,即#E

余留输入串栈:不变,#

ACTION:1接受#,acc

至此,acc已出现,结束


三、练习

接下来,可以先自己练习一下,之后对答案

已知文法如下:

S→aAcBe

A→b

B→d

1、拓广文法并编号

0  E→S

1  S→aAcBe

2  A→b

3  B→d

2、构造活前缀的DFA

3、构造LR(0)分析表

状态ACTIONGOTO
abcde#SAB
0S21
1acc
2S43
3S6
4r2r2r2r2r2r2
5r3r3r3r3r3r3
6S57
7S8
8r1r1r1r1r1r1

4、对于输入串abcde的分析过程

步骤状态栈符号栈余留输入串栈ACTIONGOTO
00#abcde#2
102#abcde#4
2024#abcde#23
3023#aAcde#6
40236#aAcde#5
502365#aAcde#37
602367#aAcBe#8
7023678#aAcBe#11
801#S#acc

至此,分析成功

另外:内容较多,若有纰漏,请提醒,感谢

第三次上机—语法分析1 目的:熟练掌握自上而下的语法分析方法,并能用C++程序实现。 要求: 1. 使用的文法如下: E ® TE ¢ E ¢ ® + TE ¢ | e T ® FT ¢ T ¢ ® * FT ¢ | e F ® (E) | id 2. 对于任意给定的输入(词法记号流)进行语法分析,递归下降方法和非递归预测分析方法可以任选其一来实现。 3. 要有一定的错误处理功能。即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。可以参考书上介绍的同步记号集合来处理。 可能的出错情况:idid*id, id**id, (id+id, +id*+id …… 4. 输入以#结尾,输出推导过程中使用到的产生式。例如: 输入:id+id*id# 输出:E ® TE ¢ T ® FT ¢ F ® id E ¢ ® + TE ¢ T ® FT ¢ …… 如果输入有错误,则在输出中要体现是跳过输入的某些记号了,还是弹栈,弹出某个非终结符或者是终结符了,同时给出相应的出错提示信息。比如: idid*id对应的出错信息是:“输入跳过记号id,用户多输入了一个id”; id**id对应的出错信息是:“弹栈,弹出非终结符F,用户少输入了一个id” (id+id对应的出错信息是:“弹栈,弹出终结符 ) ,用户少输入了一个右括号(或者说,括号不匹配)” 有余力的同学可进一步考虑如下扩展: 1. 将递归下降方法和非递归预测分析方法都实现 2. 在语法分析过程中调用第二次上机的结果,即利用词法分析器来返回一个记号给语法分析器。 3. 写First和Follow函数,实现其求解过程。 测试文法: A->BCDE B->aBA|ε C->F|ε D->b|c|ε E->e|ε F->d|ε
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值