首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >有没有办法把这个语法变成LALR(1)?

有没有办法把这个语法变成LALR(1)?
EN

Stack Overflow用户
提问于 2013-05-01 16:35:19
回答 2查看 580关注 0票数 1

我有一个包含如下规则的语法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A -> pq
B -> pr

Block -> { Astar Bstar }

Astar -> Astar A
       | epsilon

Bstar -> Bstar B
       | epsilon

有没有办法把这个语法转换成LALR(1)?据我所知,如果解析器在块中看到p,则存在shift/educe冲突。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-01 17:54:18

您的语言是正则语言,等同于正则表达式\{(pq)*(pr)*\}。问题是,任何到语法的简单转换都需要两个字符的先行检查,以查看p后面是否有qr

现在您已经将其标记为yaccparsing,所以不清楚您是在寻找一个实用的答案“您如何处理这个问题”,还是一个理论上的答案“这种语言是否有一种LALR(1)语法”。

对于实际的答案,解决方案是将AB的识别转移到词法分析器中,在该词法分析器中将字符序列pqpr识别为标记AB。因为lex/flex使用DFA并回溯到最长匹配的令牌,所以它们在这里没有任何问题。

对于理论上的答案,您需要转换语法以消除对先行的需要。有问题的构造是(pq)*(pr)* (大括号是不相关的),它等同于p(qp)*(rp)*r | p(qp)*q | epsilon,它建议使用如下语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Block -> { p Astar Bstar r }
       | { p Astar q }
       | { }
A -> q p
B -> r p
Astar -> Astar A | epsilon
Bstar -> Bstar B | epsilon

另一种方法是对star规则进行分解,使其不匹配空字符串:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Block -> { Aplus Bplus }
       | { Aplus }
       | { Bplus }
       | { }
A -> p q
B -> p r
Aplus -> Aplus A | A
Bplus -> Bplus B | B

为同一种语言提供了两种截然不同的LALR(1)语法。

票数 4
EN

Stack Overflow用户

发布于 2013-05-01 18:28:45

让我们首先看看为什么会出现LALR(1)冲突,然后看看是否可以重新编写语法,使其成为LALR(1)。

要了解语法不是LALR(1)的原因,让我们从计算语法的LR(1)配置集开始:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(1)
S'     -> .Block [$]
Block  -> .{ Astar Bstar } [$]

(2)
S'     -> Block. [$]

(3)
Block -> { . Astar Bstar } [$]
Astar -> .Astar A [ }p ]
Astar -> .epsilon [ }p ]

(4)
Block -> { Astar . Bstar } [$]
Astar -> Astar .A [ }p]
A     -> .pq [}p]
Bstar -> .epsilon [ }p ]
Bstar -> . Bstar B [ }p ]

在这一点上,我们可以停止了,因为我们在符号p上的状态(4)中有一个shift/reduce混淆:你是为A -> .pq [ {p ]移位p,还是减少BStar -> .epsilon [ }p ]?由于LR(1)语法中存在移位/归约冲突,因此该语法根本不是LR(1),这意味着它不可能是LALR(1) (因为每个LALR(1)语法也是LR(1)语法)。

从根本上说,问题是当解析器看到一个p时,它不能判断它是在看A的开头(意味着它需要移动它),还是没有更多的A了,它正在看一个B的开头(意思是它需要减少Bstar -> epsilon)。

为了解决这个问题,让我们看看如果我们做一个小的调整会发生什么。我们遇到的问题是,解析器需要在看到p时立即确定是移位还是缩减。如果我们给它时间来推迟决定,先看p,然后再看后续字符,会怎么样?为此,让我们通过重写来稍微更改一下您的语法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Bstar -> epsilon
Bstar -> Bstar B

作为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Bstar -> epsilon
Bstar -> B Bstar

现在,解析器可以在决定要做什么之前查看更多的标记。如果它查看的是pq,那么它知道它没有查看任何与B相关的内容。如果它看到pr,它就知道它正在寻找B,因此可以开始进行第二种类型的生成。让我们看看如果我们这样做,LR(1)状态会发生什么:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(1)
S'     -> .Block [$]
Block  -> .{ Astar Bstar } [$]

(2)
S'     -> Block. [$]

(3)
Block -> { . Astar Bstar } [$]
Astar -> .Astar A [ }p ]
Astar -> .epsilon [ }p ]

(4)
Block -> { Astar . Bstar } [$]
Astar -> Astar .A [ }p]
A     -> .pq [}p]
Bstar -> .epsilon [ } ]
Bstar -> . B Bstar [ } ]
B     -> .pr [}]

(5)
Block -> { Astar Bstar . } [$]

(6)
Block -> { Astar Bstar } . [$]

(7)
A     -> p.q [}p]
B     -> p.r [}]

(8)
A     -> .pq [}p]

(9)
B     -> pr. [}]

(10)
Bstar -> B . Bstar [ } ]
Bstar -> . B Bstar [ } ]
B     -> .pr [}]

(11)
B     -> p.r [}]

请注意,我们原来的shift/reduce冲突已经消失了,并且这个新语法根本不再有任何shift/reduce冲突。此外,由于没有任何具有相同核心的状态对,因此上面的状态集也是我们的LALR(1)表中的状态集。因此,上面的语法确实是LALR(1),并且我们根本没有改变语法的含义。

希望这能有所帮助!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16322348

复制
相关文章
在Android中显示APNG动图
APNG(Animated Portable Network Graphics)是一个基于PNG(Portable Network Graphics)的位图动画格式,用途类似GIF,其诞生的目的是为了替代老旧的 GIF 格式。
Clayman Twinkle
2019/04/04
17.1K1
在Android中显示APNG动图
Flutter 应用程序中显示应用程序通知
要使用 Overlay 功能,我们必须将 Material 应用程序包装在OverlaySupport小部件中。
徐建国
2021/11/30
1.8K0
Flutter 应用程序中显示应用程序通知
Android应用程序中的多个Activity的显示创建和调用[通俗易懂]
http://download.csdn.net/detail/u011936142/7429455
全栈程序员站长
2022/07/08
1.5K0
Android应用程序中的多个Activity的显示创建和调用[通俗易懂]
Android应用中如何调用系统闹钟及日历
今天开发一个小应用需要添加一个响应事件实现跳转到闹钟和日历,在遍访网上各种回答后得出了最简单答案,现记下来供自己与网友共享。
张拭心 shixinzhang
2022/11/30
1.9K0
Android TextView中显示图片
Android官方给我们提供的Html类下面的fromHtml方法 当你需要转换的HTML代码是带图片的,比如<IMG/>,那么你就需要使用到重载的第二个方法了,这个方法里面有个ImageGetter对象,实现这个类会发现它回调了一个抽象getDrawable方法,在这个方法里,我们可以进行远程图片的下载获取,本地资源图片的获取等。第三个参数TagHandler是用来自定义一些不属于HTML代码的一些标签,一般我们不会去用到,直接置为null即可 package com.example.mytestdemo
欢醉
2018/01/22
1.6K0
lunar="false",日历插件不显示农历
前面使用过组件uni-calendar,有的时候,在实现一个大点的效果的时候,为了使界面看上去更加的简洁,是不需要展示农历日期的,其实很简单,只需要将lunar="true" 改成lunar="false" 即可。
王小婷
2020/02/13
2.4K0
lunar="false",日历插件不显示农历
在DataGrid中显示图片
    DadaGrid 是 ASP.NET 编程中一个很重要的控件,其优良的可定制功能为提高它的表现力提供了极大的方便。除了与数据源直接绑定以外,我们还可以通过列绑定模板对 DataGrid 的列进行自定义,来按照我们设定的格式显示数据。
Java架构师必看
2021/03/22
3.4K0
Android-日历CalendarView使用
2.在主活动中 通过设置setOnDataChangeListener() 来为其添加监听事件
圆号本昊
2021/09/24
1.9K0
Android-日历CalendarView使用
在日历中订阅腾讯待办,了解一下?
在我们的待办清单里,可能会记录着这样的日程: 对于这些有deadline的待办事项,如果想要更加直观和清晰地在日历应用上查看和管理,应该如何实现? 这时,你只需要一个URL,就可以在其他日历应用中轻松订阅腾讯待办。即便是脱离了待办小程序,也能在日历中看到设置了日期的未完成待办事项。 哪些日历可以订阅腾讯待办? 支持ics格式的URL订阅的日历:比如Outlook日历、macOS、iOS、部分安卓机型以及其他第三方日历等。 其他更多机型,如果有数据同步需求,可以到官方社区留言。 官方社区:https:
腾讯云DNSPod团队
2021/09/18
1.3K0
在日历中订阅腾讯待办,了解一下?
对于这些有deadline的待办事项,如果想要更加直观和清晰地在日历应用上查看和管理,应该如何实现?
腾讯待办
2021/09/29
9520
在日历中订阅腾讯待办,了解一下?
Android 应用程序窗口显示状态操作(requestWindowFeature()的应用)
我们在开发程序是常常会须要软件全屏显示、自己定义标题(使用button等控件)和其它的需求,今天这一讲就是怎样控制Android应用程序的窗口显示.
全栈程序员站长
2022/07/05
1.2K0
Android 应用程序窗口显示状态操作(requestWindowFeature()的应用)
[译] 在 Android Instant App(安卓即时应用程序)中启用 ProGuard (混淆)
原文地址:Enabling ProGuard in an Android Instant App 原文作者:Wojtek Kaliciński 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:JayZhaoBoy 校对者:hanliuxin5 Instant Apps(即时应用)和 4 MB 字节的限制 把一个已经存在的应用程序转换成 Android Instant App(安卓即时应用程序)是很有挑战性的,但对于模块及结构化你的项目而言却是一个很好的练习,更
Android 开发者
2018/05/31
2.6K0
[先行者周末课程] 日历组件的开发思路讲解&&日历组件在实际工作中的使用方式
各位同学们大家好,今天又到了周日,视频课程的时候。上次咱们讲的是日历组件。 简短的回顾一下上周的内容,免得同学们一时断篇,想不起来身在何方。日历这种东西,初学者,包括我在内,多数都会有些不知从哪里下手。会有些不太理解这东西是怎么把每个月的格,都画出来的。 其实,单纯的日历,非常简单。本质就是Date()对象的应用。 日历是几行七列的表格,那么肯定是for...for循环嵌套的了。如果哪个同学不熟悉嵌套for循环,那肯定是没写过99乘法表。 ============ 今天这次课就是详细的给大家讲一个日历的内部
web前端教室
2018/02/06
2.7K0
[先行者周末课程] 日历组件的开发思路讲解&&日历组件在实际工作中的使用方式
在 .NET 应用程序中运行 JavaScript
前几天我在做一个副业,意识到我需要使用一些 JavaScript 功能。一想到要再次处理 Node.js 和 npm,我就完全放弃了,所以我决定研究一下在 .NET 应用程序中运行 JavaScript 的可能性。很疯狂吧?实际上,这出乎意料的简单。
独立观察员
2022/12/06
2.6K0
在 .NET 应用程序中运行 JavaScript
▲ Android 自定义日历签到效果
如果需要更多的定制化需求请直接看我这篇,Android 使用RecycleView自定义日历签到效果 ,自定义日历2.0的功能远远大于我这个篇1.0的效果。
全栈程序员站长
2021/04/07
9090
Android向系统日历添加日程事件
在项目开发过程中,有时会有预约提醒、定时提醒等需求,这时我们可以使用系统日历来辅助提醒。通过向系统日历中写入事件、设置提醒方式(闹钟),实现到达某个特定的时间自动提醒的功能。这样做的好处是由于提醒功能是交付给系统日历来做,不会出现应用被杀情况,能够做到准时提醒。 一般来说实现向系统日历中读写事件一般有以下几个步骤: (1)需要有读写日历权限; (2)如果没有日历账户需要先创建账户; (3)实现日历事件增删改查、提醒功能;
developerHaoz
2022/05/13
3.2K0
❤️【python入门项目】使用 Tkinter 的 日历 GUI 应用程序❤️
本文章为系列文章,共三个 python 入门项目。初学者可以尝试实现这些项目,并在 Python 编译环境中动手操作。
海拥
2021/08/24
2.8K0
点击加载更多

相似问题

如何从派生类复制构造函数调用基类复制构造函数?

20

从派生类调用构造函数

25

从复制构造函数调用构造函数

23

从派生类构造函数调用基类构造函数

44

从派生类构造函数调用基类构造函数

53
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文