本文主要说明LR解析过程中关于BNF的典型冲突如何在LR中解决

冲突一般分为两种:

  • shift/reduce错误
  • redure/redure错误

下面分别解释两种冲突

1. shift/reduce错误

这种错误是因为 分析器在这种情况下不知道是归约还是移进导致的。

2. redure/redure错误

这种错误是因为,解析器在解析栈中规则时发现有多个规则可以进行归约。rejected rule 会指出跟哪个rule冲突

我们首先举个例子。

例子1

文法如下: 这是一个简单的解析

"<><><><>"

"<>"

""

class classnam {}

def p_start(p):
'''
start : typeArguments
''' def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
''' def p_typeArgument(p):
'''
typeArgument : LESS MORE
| empty
''' def p_empty( p ):
'''empty : '''

这时产生的错误。

WARNING:
WARNING: Conflicts:
WARNING:
WARNING: shift/reduce conflict for LESS in state 0 resolved as shift
WARNING: shift/reduce conflict for LESS in state 2 resolved as shift
WARNING: reduce/reduce conflict in state 2 resolved using rule (start -> typeArguments)
WARNING: rejected rule (empty -> <empty>) in state 2

那么下面看看如何来解决这个问题。

def p_start(p):
'''
start : typeArguments
| empty
''' def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
''' def p_typeArgument(p):
'''
typeArgument : LESS MORE
''' def p_empty( p ):
'''empty : '''

这个问题出现在

def p_typeArgument(p):
'''
typeArgument : LESS MORE
| empty
'''

身上,因为empty比较特殊可以告诉yacc可以reduce,因为结束了。而LESS还需要shift.

而在 typeArgument 身上也出现了一个问题就是到底 typeArgument是redure成empty还是 LESS MORE形式。

例子2

def p_start(p):
'''
start : typeArguments
''' def p_typeArguments(p):
'''
typeArguments : typeArgument
| typeArguments typeArgument
''' def p_typeArgument(p):
'''
typeArgument : LESS MORE
| list
''' def p_list(p):
'''
list : LESS MORE
''' def p_empty( p ):
'''empty : '''

这个问题是比较典型的redure冲突

出现在 typeArgument和list的冲突上。

WARNING:
WARNING: Conflicts:
WARNING:
WARNING: reduce/reduce conflict in state 7 resolved using rule (typeArgument -> LESS MORE)
WARNING: rejected rule (list -> LESS MORE) in state 7
WARNING: Rule (list -> LESS MORE) is never reduced

这种情况就是因为在一个规则树中出现了两个同样的规则在同一个里面。

例子3

这个例子算是一个较为经典的shift/redure的问题。

expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression
| LPAREN expression RPAREN
| NUMBER

如果我们不只用优先级来定义,那么我们可以如下方法解决优先级别的问题:

def p_start(p):
'''
start : expression
''' def p_expression(p):
'''
expression : multExpression
| expression PLUS multExpression
| expression MINUS multExpression
''' def p_multExpression(p):
'''
multExpression : subExpression
| multExpression TIMES subExpression
| multExpression DIVIDE subExpression
''' def p_subExpression(p):
'''
subExpression : LPAREN expression RPAREN
| primary
''' def p_primary(p):
'''
primary : NUMBER
'''

在java中也可以使用如上方法来定义一个expression来完成整个expression树的解析过程。因为过于复杂,所以这里不就写了,有兴趣的可以看java 7 lanaguage

上面3个例子都比较典型,基本能把大部分书写LR文法的时候遇到的问题解决掉。

参考:https://www.ituring.com.cn/article/52229

LR编写grammar中的问题和解决方法的更多相关文章

  1. PowerShell因为在此系统中禁止执行脚本解决方法

    PowerShell因为在此系统中禁止执行脚本解决方法   在Powershell直接脚本时会出现: 无法加载文件 ******.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 " ...

  2. (转)ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法

    早上同事用PL/SQL连接虚拟机中的Oracle数据库,发现又报了"ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务"错误,帮其解决后,发现很多人遇到过这样的问 ...

  3. ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法

    ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法 (2016-10-21 16:49:53)   今天在做一个查询的时候,报了一个"ORA-01652无法通过 ...

  4. Oracle中的 UPDATE FROM 解决方法

    转:http://www.cnblogs.com/JasonLiao/archive/2009/12/23/1630895.html Oracle中的 UPDATE FROM 解决方法 在表的更新操作 ...

  5. win7 安装过程中遇到的错误解决方法

    win7 安装过程中遇到的错误解决方法 windows安装无法继续.若要安装windows 请单击 确定 重新启动计算机: 当 出现如上提示的时候,按下shift+f10 会打开命令窗口,进入到C:\ ...

  6. [转载]Ubuntu 14.04中root 密码忘记解决方法

      Ubuntu 14.04中root 密码忘记解决方法 方法一: 如果用户具有sudo权限,那么直接可以运行如下命令: #sudo su root #passwd #更改密码 或者直接运行sudo ...

  7. oracle中can not set解决方法

    原因:set autotrace on和set trimspool on在pl\sql中使用不了 解决方法:在window环境中,使用cmd命令,sqlplus user_name/password@ ...

  8. 【转】eclipse中window->preference选项中没有tomcat的解决方法

    eclipse中window->preference选项中没有tomcat的解决方法 2011-09-09 13:46:35|  分类: eclipse|字号 订阅 其实一共有好几种方法,这只是 ...

  9. Oracle更新表字段时内容中含有特殊字符&的解决方法

    今天在做 Oracle表字段更新时出现了特殊字符&,导致无法更新. 这个问题是第二次碰到了,所以在此记录下,以备后用. 举例: update t set col1='A&B' wher ...

随机推荐

  1. Kotlin开发springboot项目(二)

    Kotlin开发springboot项目(二) 中文学习网站: https://www.kotlincn.net/ 研究一下kotlin的demo: https://github.com/JetBra ...

  2. Html快速上手

    Html 概述 HTML文档 Doctype Meta Title Link Style Script 常用标签 各种符号 p 和 br a 标签 H 标签 select input:checkbox ...

  3. 任务型对话(二)—— DST(对话状态追踪)

    1,概述 关于任务型对话的简介看任务型对话(一)—— NLU(意识识别和槽值填充). 首先我们来看下对话状态和DST的定义. 对话状态:在$t$时刻,结合当前的对话历史和当前的用户输入来给出当前每个s ...

  4. 201871010117-石欣钰《面向对象程序设计(Java)》第四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  5. flask实战-个人博客-数据库-生成虚拟数据 --

    3.生成虚拟数据 为了方便编写程序前台和后台功能,我们在创建数据库模型后就编写生成虚拟数据的函数. 1)管理员 用于生成虚拟管理员信息的fake_admin()函数如下所示: personalBlog ...

  6. home_url()用法小结|wordpress函数

    home_url()检索可访问当前站点的URL(推荐将<?php bloginfo('url'); ?>用<?php home_url(); ?>来替代),使用适当的协议返回' ...

  7. Code Chef May Challenge 2019题解

    传送门 \(REDONE\) 贡献可以拆成\(X(Y+1)+Y\),那么一个数\(x\)的贡献对最终答案的贡献就是\(x(a_1+1)(a_2+1)...\),那么最终答案肯定是\(\sum\limi ...

  8. 【oracle】update 某字段为null

    字段 = null 注意这个字段要可以为空

  9. hadoop java.io.EOFException: Unexpected end of input stream

    执行hadoop 报错 java.io.EOFException: Unexpected end of input stream at org.apache.hadoop.io.compress.De ...

  10. 推荐:Markdown编辑软件 --- 小书匠

    推荐:Markdown编辑软件 --- 小书匠 小书匠 使用手册 Markdown编辑工具推荐小书匠工具,功能丰富,简单使用,可以一步导文件至博客园主页. 概要 小书匠编辑器是一款专为markdown ...