嘿伙计我遇到一些野牛代码有问题...编译完这段代码后,我得到58转/减少和40减少/减少冲突...有关如何限制它们的任何提示,或者请指点如何做到这一点的好指南?提前致谢!! (以T_开头的所有东西,比如T_get都是在此代码上面定义的标记)
start:T_get G
|T_head G
|T_post G
;
G:url canon
;
url: T_http T_dslash T_host T_abs_path
;
canon:GH canon|RH canon|EH canon|MB
;
GH:T_con T_akt T_seq GH|T_date T_akt D GH|T_trans T GH|
;
D:T_day T_slash T_month T_slash T_year T_hour T_akt T_min
;
T:T_chunked |T_gzip |T_deflate
;
RH:T_acc T_akt T_seq RH|T_ref T_akt T_seq RH|T_user T_akt T_seq RH|
;
EH:T_content T_akt T_seq EH|T_exp T_akt T_seq EH|
;
MB:T_seq|
;
%%
int main(){
yyparse();
}
即使您没有时间研究代码中的逻辑,我也会感谢这些冲突的一般帮助,例如它们是如何生成的等等
答案 0 :(得分:4)
使用bison的-v
选项获取详细输出,给出生成的解析器中的所有状态和冲突。如果你这样做,你会看到类似的状态:
state 7
4 G: url . canon
T_acc shift, and go to state 12
:
T_trans shift, and go to state 19
T_user shift, and go to state 20
$end reduce using rule 13 (GH)
$end [reduce using rule 21 (RH)]
$end [reduce using rule 24 (EH)]
$end [reduce using rule 26 (MB)]
T_acc [reduce using rule 13 (GH)]
:
这告诉您,当解析器看到url
并且希望识别canon
时,它无法告诉该做什么 - 它是否应该识别出空GH
1}},RH
,EH
或MB
,还是应该移动令牌以识别其中的非空??
这些冲突都来自语法中的基本歧义 - 您有一个canon
规则,其中包含0个或多个重复的GH
,RH
和/或{{ 1}},这些规则中的每一个都由0或更多的重复组成。所以它无法告诉要插入到解析树中的多少空事物(因为它们不消耗任何输入,可以添加任意数字),并且不知道是否将类似的事物分组为单个EH
(或GH
或RH
)或多个不同的。
所以要解决这个问题,你需要决定你想要什么。最有可能的是,你不关心EH
/ GH
/ RH
结构的分组,也不关心空结构,所以你应该摆脱递归对于这些规则:
EH
现在,这些规则中的每一个都将匹配一个构造,如果您有多个,则它们将按GH:T_con T_akt T_seq|T_date T_akt D|T_trans T;
RH:T_acc T_akt T_seq|T_ref T_akt T_seq|T_user T_akt T_seq;
EH:T_content T_akt T_seq|T_exp T_akt T_seq;
规则组合在一起。这修复了你所有的冲突,但仍然留下了一个潜在的问题 - 你的canon
规则是正确的递归,所以在减少任何规则之前将整个输入吸入堆栈(因为对于右递归,它会减少正确的-向左)。你可能想让规则保持递归 - 野牛的一般规则是总是使用左递归而不是正确的递归,除非你因某种原因需要正确的递归。这给你一个语法:
canon