yacc - Yacc 冲突我无法解决
问题描述
我一直在尝试修复我的 yacc 规范中的 shift/reduce 冲突,但我似乎找不到它在哪里。
%union{
char* valueBase;
char* correspondencia;
}
%token pal palT palC
%type <valueBase> pal
%type <correspondencia> palT palC Smth
%%
Dicionario : Traducao
| Dicionario Traducao
;
Traducao : Palavra Correspondencia
;
Palavra : Base Delim
| Exp
;
Delim :
| ':'
;
Correspondencia :
| palC {printf("PT Tradução: %s\n",$1);}
;
Exp : Smth '-' Smth {aux = yylval.valueBase; printf("PT Tradução: %s %s %s\n", $1, aux, $3);}
;
Smth : palT {$$ = strdup($1);}
| {$$ = "";}
;
Base : pal {printf("EN Palavra base: %s\n",$1);}
;
任何帮助查找和解决此冲突将不胜感激。
解决方案
因此,查看语法中的 y.output 文件,您在状态 13 中存在移位/减少冲突:
State 13
10 Exp: Smth '-' . Smth
palT shift, and go to state 2
palT [reduce using rule 12 (Smth)]
$default reduce using rule 12 (Smth)
Smth go to state 16
基本上,这就是说,当Exp
在看到 aSmth '-'
并查看前瞻之后解析 a 时palT
,它不知道是否应该减少一个空Smth
来完成Exp
(留下palT
作为稍后构造的一部分)或转移palT
so然后可以将其减少(识别)为Smth
完成 this的 a Exp
。
您正在识别的语言是一个或多个 的序列Traducao
,每个由 aPalavra
和一个可选的palC
(Correspondencia
可能是 apalC
或空)组成。这意味着您可能有一个Palavra
直接跟随另一个Palavra
(Correspondencia
第一个是空的)。Palavra
所以解析器需要通过查看它的当前状态和一个前瞻标记来找到一个和下一个之间的边界,这是一个问题。
特别是当你有一个像 一样的输入时PalT '-' PalT '-' PalT
,就是两个连续的,但是中间是属于第一个还是第二个Palavra
就不清楚了。PalT
它是模棱两可的,因为无论哪种方式都可以成功解析。
如果您希望解析器尽可能多地接受 first Palavra
,那么您可以接受默认分辨率(移位)。如果这是错误的并且您需要其他解释,那么您将需要更多的前瞻性来识别这种情况,因为这取决于第二秒'-'
之后是否有第二秒palT
或其他什么。
推荐阅读
- facebook-opengraph - property="og:type" content="website" 和 property="og:type" content="article" 有什么区别
- python - 如何减少输出数量?
- javascript - 在 javascript / moment.js 中获取每周的第一天
- android - 我是新手JNI,为什么我的android jni C++ try块没有捕获异常
- ios - 在字典 Swift 中更新字典的值
- android - android studio 渲染错误
- angular - Angular 8 Form Array返回找不到带有路径的控件:'变量-> 0'
- docker - 没有 Docker 注册表的 Jenkins CI/CD 部署到 AWS EKS
- python - django.core.exceptions.ImproperlyConfigured:错误来了
- javascript - react、redux、node app中prop不从true变为false