本文主要说明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. vmware关闭嘟嘟嘟嘟警告

    在使用VMware workstation时,安装的windows或者Linux遇到错误操作时,会发生刺耳的嘟嘟声.如何关闭呢?在VMware虚拟机windows系统中的命令提示符处键入以下命令, 然 ...

  2. c++ c的拓展

    C++对c的拓展之, 引用和const关键字 bool类型关键字 C++中的布尔类型 C++在C语言的基本类型系统之上增加了bool C++中的bool可取的值只有true和false 理论上bool ...

  3. libass简明教程

    [时间:2019-05] [状态:Open] [关键词:字幕,libass,字幕渲染,ffmpeg, subtitles, video filter] 0 引言 libass库则是一个轻量级的对ASS ...

  4. python 和 R 中的整数序列

    python 中的 range() 函数是很常用的,R  中相应的函数是 seq(), 其实,R 中的“ :”也能代替 python 中的 range() 函数. 1.生成升序整数序列 python: ...

  5. MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)

    题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...

  6. Python3 if 变量variable SQL where 语句拼接

    最近在写python3的项目,在实际中运用到了根据 if 判断变量variable ,然后去拼接where子句.但是在百度.BING搜索中未找到合适的答案,这是自己想出来的典型php写法,这里做一下记 ...

  7. CentOS7 下使用 Firewall防火墙系统封禁允许IP和端口的访问 端口转发 IP转发方法

    CENTOS7的防火墙系统默认已经从iptable改成了firewall,使用方法也有所不同,下面是详细介绍 一.管理端口 列出 dmz 级别的被允许的进入端口 # firewall-cmd --zo ...

  8. Git常用基础命令

    要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某 个项目时,需要管理这些远程仓库 ...

  9. day 19

    If you think you can, you can. And if you think you can't, you're right.

  10. haproxy 配置文件详解 之 WEB监控平台

    HAProxy 虽然实现了服务的故障转移,但是在主机或者服务出现故障的时候,并不能发出通知告知运维人员,这对于及时性要求很高的业务系统来说,是非常不便的,不过,HAProxy 似乎也考虑到了这一点,在 ...