总结

总结:

  • 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"可能被两条规则消费:

  1. “空” 被规约为sequence,sequence+"word"规约为sequence。
  2. “空” 和 “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。
  • 还是选路径2:ID [reduce using rule 2 (a)]
    • rule2: a: expr
$ 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移进规约冲突案例分析(一)相关推荐

  1. 3.03 bison移进/规约冲突和操作符优先级

    如果你已经储备bison的相关基础知识,阅读理解下面的代码会轻松得多.没有bison基础的同学请点击查看bison基本的语法规则及相关介绍. 移进/规约冲突一般是由文法二义性造成的,关于二义性可以看看 ...

  2. 编译原理什么是移进规约冲突_编译原理复习题

    可以微信扫码观看 河南城建 <编译原理>复习题丨杨海振整理丨20150521 一.单项选择题 1.构造编译程序应掌握   .D a. 源程序                         ...

  3. 编译原理什么是移进规约冲突_我这个人不懂什么CPU,于是我用代码模拟出了一个...

    选自djhworld博客 作者:daniel harper 机器之心编译 参与:杜伟.张倩.李泽南 芯片的设计到底有多难?想要回答这个问题最好还是先自己实践一下.最近,来自 BBC 的一名资深软件工程 ...

  4. 擎创技术流 | java多类加载器类冲突案例分析

    众所周知,jvm类加载机制采用双亲委派机制.但在有些框架中,常常为了提供某种形式的"隔离和沙盒",自定义一种称为ChildFirst的类加载器,简单的说就是破坏了双亲委派,由自定义 ...

  5. [编译原理]构造LR分析器和SLR移进归约分析表

    目录 目标 1.基础知识引入 1.1 文法 1.2 拓广文法 1.3 全部的项目集 2. 计算文法的LR(0)项目集的.识别活前缀的DFA 2.1 分析得到各个项目集 2.2 构建SLR分析表中的移进 ...

  6. Bison 移进-归约分析

    bison 采用自底向上 (bottom-up) 的分析方法.它用到一个分析栈 (parser stack),关键有两个动作: 1. 移进 (shift)     读取的 token 移进到分析栈中. ...

  7. 微观经济学案例分析(七)

    7.1 自然垄断:中国电信行业的变化 案例内容 我国的电信化起步于上世纪六十年代,到八九十年代进入了大规模的尝试性 应用阶段,之后随着互联网的兴起进入了快速建设时期.2006年后由于信息化融 合,移动 ...

  8. SPI协议分析仪的使用介绍及flash无法启动两种案例分析

    SPI协议分析仪的使用介绍及案例分析 一.协议分析仪介绍 Kingst LA5016 USB 协议分析仪,支持众多标准协议解析,包括:UART/RS232/485,I2C,SPI,CAN,SMBUS等 ...

  9. 图解通信原理与案例分析-35:以太网MAC层的通信原理--MAC帧格式与调度策略:载波侦听与冲突检测CSMA/CD、载波侦听与冲突避免(信道空闲保证)CSMA/CA、流控

    以太网协议已经是非常成熟的通信技术,本文旨在在汇总以太网MAC层的协议,以便于与其他通信技术的MAC层作为比较,如4G LTE, 5G NR,特别是LTE在非授权频谱上的通信LAA LBT, 就是借鉴 ...

最新文章

  1. 在redhat6.3 安装oracle 11.2.0.1遇到的错误
  2. oracle19c xp安装 客户端_windows下安装oracle19c
  3. excel办公常用的宏_让领导看傻!精美168套办公常用excel模板免费领
  4. 【HDU - 2553】N皇后问题 (dfs经典问题,回溯,搜索)
  5. Java-环境搭建(Mac版)
  6. cacti监控java,Cacti监控tomcat的方法
  7. Pentium M处理器架构/微架构/流水线(1) - 流水线概述
  8. python特征选择后显示选取的特征名_python实现求特征选择的信息增益
  9. Spring Boot-面试题
  10. 第一个国产Apache 顶级项目 Kylin,了解一下!| 原力计划
  11. java split 实现_PL/SQL实现JAVA中的split()方法的例子
  12. Markdown语法(一)标题段落分割线
  13. 简历编写技巧-java开发工程师简历实战
  14. CAM350 12.1免费下载
  15. PQ分区工具超详细图文教程
  16. 1——man elf的翻译——ELF header (Ehdr)
  17. java 模块解耦_微服务架构:如何用十步解耦你的系统?
  18. 如何放大图片不模糊?教你一招
  19. 动漫人物人体结构难学么?衣物怎么画?
  20. 图像处理——单通道图像与多通道图像

热门文章

  1. 详细教程|电脑上删除的照片如何恢复?
  2. IO性能最重要的三个指标
  3. 笔记本计算机充不上电,笔记本电脑充不进电怎么办|笔记本冲不了电的解决方法...
  4. C4D渲染太慢怎么解决,为什么我的C4D老是崩溃?
  5. 逻辑代数基础介绍——数电第二章学习
  6. 九十三、Eclipse设置代码自动提示
  7. 大学四年的各种学习资源整理
  8. 怎样实现ocr文字识别技术
  9. HTML5基础----文字特效
  10. 戴尔服务器R730内部架构介绍