LR编写grammar中的问题和解决方法
本文主要说明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中的问题和解决方法的更多相关文章
- PowerShell因为在此系统中禁止执行脚本解决方法
PowerShell因为在此系统中禁止执行脚本解决方法 在Powershell直接脚本时会出现: 无法加载文件 ******.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 " ...
- (转)ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
早上同事用PL/SQL连接虚拟机中的Oracle数据库,发现又报了"ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务"错误,帮其解决后,发现很多人遇到过这样的问 ...
- ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法
ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法 (2016-10-21 16:49:53) 今天在做一个查询的时候,报了一个"ORA-01652无法通过 ...
- Oracle中的 UPDATE FROM 解决方法
转:http://www.cnblogs.com/JasonLiao/archive/2009/12/23/1630895.html Oracle中的 UPDATE FROM 解决方法 在表的更新操作 ...
- win7 安装过程中遇到的错误解决方法
win7 安装过程中遇到的错误解决方法 windows安装无法继续.若要安装windows 请单击 确定 重新启动计算机: 当 出现如上提示的时候,按下shift+f10 会打开命令窗口,进入到C:\ ...
- [转载]Ubuntu 14.04中root 密码忘记解决方法
Ubuntu 14.04中root 密码忘记解决方法 方法一: 如果用户具有sudo权限,那么直接可以运行如下命令: #sudo su root #passwd #更改密码 或者直接运行sudo ...
- oracle中can not set解决方法
原因:set autotrace on和set trimspool on在pl\sql中使用不了 解决方法:在window环境中,使用cmd命令,sqlplus user_name/password@ ...
- 【转】eclipse中window->preference选项中没有tomcat的解决方法
eclipse中window->preference选项中没有tomcat的解决方法 2011-09-09 13:46:35| 分类: eclipse|字号 订阅 其实一共有好几种方法,这只是 ...
- Oracle更新表字段时内容中含有特殊字符&的解决方法
今天在做 Oracle表字段更新时出现了特殊字符&,导致无法更新. 这个问题是第二次碰到了,所以在此记录下,以备后用. 举例: update t set col1='A&B' wher ...
随机推荐
- MySQL——基本概念
1.数据库:是一个长期存储在计算机内的.有组织的.有共享的.统一管理的数据集合.它是一个按数据结构来存储的和管理数据的计算机软件系统,即数据库包含两层含义:保管数据的“仓库”,以及数据管理的方法和技术 ...
- scrapy-redis 0.6.8 配置信息
很多博客的db参数配置都不能用,所以记录一下该版本可用的配置 #启用Redis调度存储请求队列 SCHEDULER = "scrapy_redis.scheduler.Scheduler&q ...
- postgresql设置max_connections太大无法启动 (转载)
本篇随笔转载自https://my.oschina.net/u/2381678/blog/552346. 在生产环境postgresql中,需要调整最大链接数,但是调整后无法启动 错误的意思就是内核中 ...
- 团队第六次作业:Beta版本冲刺成绩汇总
一.作业题目 团队第六次作业:Beta版本冲刺 二.作业评分标准 博客评分规则(总分100)博客要求 1.冲刺博客每篇占20分.(3次) - (1) 各成员该天完成的工作,以及明天的任务安排(表格的形 ...
- php策略模式(strategy pattern)
... <?php /* The strategy pattern defines a family of algorithms, each of which is encapsulated a ...
- 28 让树莓派开机“说”出自己的IP地址
http://shumeipai.nxez.com/2019/02/02/analogue-audio-redux.html 树莓派音频口底噪消除的方法
- (9-4 )deepsort在ubuntu1604下配置
Deep Sort with PyTorch YOLO https://github.com/ZQPei/deep_sort_pytorch 查看python版本 python3 --version ...
- PDB files out of the debugger
我想我不需要强调在调试时拥有有效的PDB文件有多重要.通常,PDB文件是由调试器静默加载的,并且您很高兴在modules窗口中看到解析的所有符号.不幸的是,您还可能遇到调试器找不到匹配符号的情况.其原 ...
- jieba分词wordcloud词云
1.jieba库的基本介绍 (1).jieba是优秀的中文分词第三方库 中文文本需要通过分词获得单个的词语 jieba是优秀的中文分词第三方库,需要额外安装 jieba库提供三种分词模式,最简单只需掌 ...
- mysql where/having
select * from t1 where id<5;select * from t1 where id<5; where 从t1中筛选内容 而having从*中筛选内容