YACC移进规约冲突案例分析(一)
总结
总结:
- bison给出的用例是发现冲突的最便捷方法。
- 第一种用例:明确用例(一个Example),直接反应问题。
- 第二种用例:混淆用例(两个Example),解析器无法区分两条语句。
- 也可以看output输出的状态机中给出的两条冲突规则,可读性比较差。
- 方括号括起来的是冲突的路径。
总结:
- bison给出用例的第二种情况,有时会比较难以理解。为什么呢?
- 因为他给的用例可能是经过reduce的上层用例,真正冲突的地方在语法树下层。
案例一:返回一个Example的场景(简单)
冲突报错返回一个明确用例的场景。
sequence.y
%%
sequence:%empty
| maybeword
| sequence "word"
;
maybeword:%empty
| "word"
;
编译
$ bison -Wcex --report='cex' sequence.y
sequence.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
sequence.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
共有三条冲突,下面是用例:
【冲突一】
注意看用例Example,提供的是一个 "空 word"的例子。
用例说明比较清晰了,"空 word"可能被两条规则消费:
- “空” 被规约为sequence,sequence+"word"规约为sequence。
- “空” 和 “word” 都被移进位sequence
sequence.y: warning: shift/reduce conflict on t0ken "word" [-Wcounterexamples]Example: . "word"Shift derivationsequence`-> 2: maybeword`-> 5: . "word"Reduce derivationsequence`-> 3: sequence "word"`-> 1: %empty .
【冲突二】
输入空的时候,有两个规约路径。
sequence.y: warning: reduce/reduce conflict on tokens $end, "word" [-Wcounterexamples]Example: .First reduce derivationsequence`-> 1: %empty .Second reduce derivationsequence`-> 2: maybeword`-> 4: %empty .
output
下面看看output文件怎么阅读。
- 最上面会有告警和冲突的汇总。
- Grammar开始是规则区,y文件中的每一行规则在这里编号,后面使用时会使用编号代替。
- State 0开始是状态区,状态转移如果不唯一的话,会在State区列出例子和冲突选项。
- 状态机转移请看下一个例子。
$ cat sequence.output
Rules useless in parser due to conflicts4 maybeword: %emptyState 0 conflicts: 1 shift/reduce, 2 reduce/reduceGrammar0 $accept: sequence $end1 sequence: %empty2 | maybeword3 | sequence "word"4 maybeword: %empty5 | "word"Terminals, with rules where they appear$end (0) 0error (256)"word" (258) 3 5Nonterminals, with rules where they appear$accept (4)on left: 0sequence (5)on left: 1 2 3on right: 0 3maybeword (6)on left: 4 5on right: 2State 00 $accept: . sequence $end"word" shift, and go to state 1$end reduce using rule 1 (sequence)$end [reduce using rule 4 (maybeword)]"word" [reduce using rule 1 (sequence)]"word" [reduce using rule 4 (maybeword)]$default reduce using rule 1 (sequence)sequence go to state 2maybeword go to state 3shift/reduce conflict on t0ken "word":1 sequence: %empty .5 maybeword: . "word"Example: . "word"Shift derivationsequence`-> 2: maybeword`-> 5: . "word"Reduce derivationsequence`-> 3: sequence "word"`-> 1: %empty .reduce/reduce conflict on t0kens $end, "word":1 sequence: %empty .4 maybeword: %empty .Example: .First reduce derivationsequence`-> 1: %empty .Second reduce derivationsequence`-> 2: maybeword`-> 4: %empty .shift/reduce conflict on t0ken "word":4 maybeword: %empty .5 maybeword: . "word"Example: . "word"Shift derivationsequence`-> 2: maybeword`-> 5: . "word"Reduce derivationsequence`-> 3: sequence "word"`-> 2: maybeword`-> 4: %empty .State 15 maybeword: "word" .$default reduce using rule 5 (maybeword)State 20 $accept: sequence . $end3 sequence: sequence . "word"$end shift, and go to state 4"word" shift, and go to state 5State 32 sequence: maybeword .$default reduce using rule 2 (sequence)State 40 $accept: sequence $end .$default acceptState 53 sequence: sequence "word" .$default reduce using rule 3 (sequence)
案例二:返回两个Example的场景(复杂递归)
冲突报错返回两个混淆用例的场景(解析器无法区分两个用例)。
ids.y
%token ID
%%
s: a ID
a: expr
expr: %empty | expr ID ','
编译
$ bison -Wcex --report='cex' ids.y
ids.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
ids.y: warning: shift/reduce conflict on token ID [-Wcounterexamples]First example: expr . ID ',' ID $endShift derivation$accept`-> 0: s $end`-> 1: a ID`-> 2: expr`-> 4: expr . ID ','Second example: expr . ID $endReduce derivation$accept`-> 0: s $end`-> 1: a ID`-> 2: expr .
ids.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]4 | a: expr| ^~~~
复杂递归的规则,bison无法计算出一个冲突的例子。
所以解析器只能给出两个反例,含义是他无法区分这两个例子的区别。
解析器需要一个look ahead token,来知道逗号是否跟在expr ID后面。
修复的方法是:expr: ID | ',' expr ID.
ids.y
%token ID
%%
s: a ID
a: expr
expr: ID | ',' expr ID
注意:
- 修复前,
expr ID
的解析是有歧义的,如果后面有逗号,应该走上面的例子;如果后面没逗号,应该走下面的例子。 - 修复后,
expr ID
的解析是稳定的,肯定会走expr reduce a; then shift ID
。
从Output来看,主要问题是无法确定:
- 选路径1:ID shift, and go to state 6
- state 6:
4 expr: expr ID . ','
->',' shift, and go to state 7
- 即ID参与`expr: expr ID . ‘,’``规则的shift。
- state 6:
- 还是选路径2:ID [reduce using rule 2 (a)]
- rule2:
a: expr
- rule2:
$ cat ids.output
Rules useless in parser due to conflicts2 a: exprState 3 conflicts: 1 shift/reduceGrammar0 $accept: s $end1 s: a ID2 a: expr3 expr: %empty4 | expr ID ','Terminals, with rules where they appear$end (0) 0',' (44) 4error (256)ID (258) 1 4Nonterminals, with rules where they appear$accept (5)on left: 0s (6)on left: 1on right: 0a (7)on left: 2on right: 1expr (8)on left: 3 4on right: 2 4State 00 $accept: . s $end$default reduce using rule 3 (expr)s go to state 1a go to state 2expr go to state 3State 10 $accept: s . $end$end shift, and go to state 4State 21 s: a . IDID shift, and go to state 5State 32 a: expr .4 expr: expr . ID ','ID shift, and go to state 6ID [reduce using rule 2 (a)]shift/reduce conflict on token ID:2 a: expr .4 expr: expr . ID ','First example: expr . ID ',' ID $endShift derivation$accept`-> 0: s $end`-> 1: a ID`-> 2: expr`-> 4: expr . ID ','Second example: expr . ID $endReduce derivation$accept`-> 0: s $end`-> 1: a ID`-> 2: expr .State 40 $accept: s $end .$default acceptState 51 s: a ID .$default reduce using rule 1 (s)State 64 expr: expr ID . ','',' shift, and go to state 7State 74 expr: expr ID ',' .$default reduce using rule 4 (expr)
修复后
Grammar0 $accept: s $end1 s: a ID2 a: expr3 expr: ID4 | ',' expr IDTerminals, with rules where they appear$end (0) 0',' (44) 4error (256)ID (258) 1 3 4Nonterminals, with rules where they appear$accept (5)on left: 0s (6)on left: 1on right: 0a (7)on left: 2on right: 1expr (8)on left: 3 4on right: 2 4State 00 $accept: . s $endID shift, and go to state 1',' shift, and go to state 2s go to state 3a go to state 4expr go to state 5State 13 expr: ID .$default reduce using rule 3 (expr)State 24 expr: ',' . expr IDID shift, and go to state 1',' shift, and go to state 2expr go to state 6State 30 $accept: s . $end$end shift, and go to state 7State 41 s: a . IDID shift, and go to state 8State 52 a: expr .$default reduce using rule 2 (a)State 64 expr: ',' expr . IDID shift, and go to state 9State 70 $accept: s $end .$default acceptState 81 s: a ID .$default reduce using rule 1 (s)State 94 expr: ',' expr ID .$default reduce using rule 4 (expr)
YACC移进规约冲突案例分析(一)相关推荐
- 3.03 bison移进/规约冲突和操作符优先级
如果你已经储备bison的相关基础知识,阅读理解下面的代码会轻松得多.没有bison基础的同学请点击查看bison基本的语法规则及相关介绍. 移进/规约冲突一般是由文法二义性造成的,关于二义性可以看看 ...
- 编译原理什么是移进规约冲突_编译原理复习题
可以微信扫码观看 河南城建 <编译原理>复习题丨杨海振整理丨20150521 一.单项选择题 1.构造编译程序应掌握 .D a. 源程序 ...
- 编译原理什么是移进规约冲突_我这个人不懂什么CPU,于是我用代码模拟出了一个...
选自djhworld博客 作者:daniel harper 机器之心编译 参与:杜伟.张倩.李泽南 芯片的设计到底有多难?想要回答这个问题最好还是先自己实践一下.最近,来自 BBC 的一名资深软件工程 ...
- 擎创技术流 | java多类加载器类冲突案例分析
众所周知,jvm类加载机制采用双亲委派机制.但在有些框架中,常常为了提供某种形式的"隔离和沙盒",自定义一种称为ChildFirst的类加载器,简单的说就是破坏了双亲委派,由自定义 ...
- [编译原理]构造LR分析器和SLR移进归约分析表
目录 目标 1.基础知识引入 1.1 文法 1.2 拓广文法 1.3 全部的项目集 2. 计算文法的LR(0)项目集的.识别活前缀的DFA 2.1 分析得到各个项目集 2.2 构建SLR分析表中的移进 ...
- Bison 移进-归约分析
bison 采用自底向上 (bottom-up) 的分析方法.它用到一个分析栈 (parser stack),关键有两个动作: 1. 移进 (shift) 读取的 token 移进到分析栈中. ...
- 微观经济学案例分析(七)
7.1 自然垄断:中国电信行业的变化 案例内容 我国的电信化起步于上世纪六十年代,到八九十年代进入了大规模的尝试性 应用阶段,之后随着互联网的兴起进入了快速建设时期.2006年后由于信息化融 合,移动 ...
- SPI协议分析仪的使用介绍及flash无法启动两种案例分析
SPI协议分析仪的使用介绍及案例分析 一.协议分析仪介绍 Kingst LA5016 USB 协议分析仪,支持众多标准协议解析,包括:UART/RS232/485,I2C,SPI,CAN,SMBUS等 ...
- 图解通信原理与案例分析-35:以太网MAC层的通信原理--MAC帧格式与调度策略:载波侦听与冲突检测CSMA/CD、载波侦听与冲突避免(信道空闲保证)CSMA/CA、流控
以太网协议已经是非常成熟的通信技术,本文旨在在汇总以太网MAC层的协议,以便于与其他通信技术的MAC层作为比较,如4G LTE, 5G NR,特别是LTE在非授权频谱上的通信LAA LBT, 就是借鉴 ...
最新文章
- 在redhat6.3 安装oracle 11.2.0.1遇到的错误
- oracle19c xp安装 客户端_windows下安装oracle19c
- excel办公常用的宏_让领导看傻!精美168套办公常用excel模板免费领
- 【HDU - 2553】N皇后问题 (dfs经典问题,回溯,搜索)
- Java-环境搭建(Mac版)
- cacti监控java,Cacti监控tomcat的方法
- Pentium M处理器架构/微架构/流水线(1) - 流水线概述
- python特征选择后显示选取的特征名_python实现求特征选择的信息增益
- Spring Boot-面试题
- 第一个国产Apache 顶级项目 Kylin,了解一下!| 原力计划
- java split 实现_PL/SQL实现JAVA中的split()方法的例子
- Markdown语法(一)标题段落分割线
- 简历编写技巧-java开发工程师简历实战
- CAM350 12.1免费下载
- PQ分区工具超详细图文教程
- 1——man elf的翻译——ELF header (Ehdr)
- java 模块解耦_微服务架构:如何用十步解耦你的系统?
- 如何放大图片不模糊?教你一招
- 动漫人物人体结构难学么?衣物怎么画?
- 图像处理——单通道图像与多通道图像