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 ...
随机推荐
- SpringBoot自定义Condition注解
最近碰到个这样的需求,需要同一套代码适配个版本数据库(数据库不同,且部分表的字段及关联关系可能会不同),即这套代码配置不同的数据库都能跑.项目采用的框架为SpringBoot+Mybatis. ...
- PHP:CURL分别以GET、POST方式请求HTTPS协议接口api【转】
1.curl以GET方式请求https协议接口 //注意:这里的$url已经包含参数了,不带参数你自己处理哦GET很简单 function curl_get_https($url){ $curl = ...
- python打印带颜色字体
设置颜色开始 :\033[显示方式;前景色;背景色m 前景色 背景色 颜色 30 40 黑色 31 41 红色 32 42 绿色 33 43 黃色 34 44 蓝色 35 45 紫红色 36 46 青 ...
- windows开启PostgreSQL数据库远程访问
1.在PostgreSQL安装目录下data文件夹,打开pg_hba.conf文件,新增允许访问的ip 2.打开postgresql.conf,将listen_addresses = 'localho ...
- Codeforces Round #605 (Div. 3)
地址:http://codeforces.com/contest/1272 A. Three Friends 仔细读题能够发现|a-b| + |a-c| + |b-c| = |R-L|*2 (其中L ...
- org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next tok
org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next tokenfound character ‘@’ th ...
- nginx secure_link_module 访问包含
server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/log/host.acce ...
- 前端html页面,手机查看
在写前端页面中,经常会在浏览器运行HTML页面,从本地文件夹中直接打开的一般都是file协议,当代码中存在http或https的链接时,HTML页面就无法正常打开,为了解决这种情况,需要在在本地开启一 ...
- 配置Maven环境变量-Eclipse/Idea添加Maven
1. 文件下载 官网下载地址:http://maven.apache.org/download.cgi 下方有我提供的下载链接. 由于下载缓慢,提供一份我的下载链接:https://www.lanzo ...
- Android 开发基础入门篇: 动态权限申请
说明: 咱们在安装APP的时候经常会看到,类似于下面的提示 goolge为了保护用户隐私,在android 6.0开始,某些隐私权限,必须用户允许以后,内部程序方可使用 这就涉及到权限动态申请问题. ...