y.output文件准确告诉您冲突的确切位置.第一个是状态4,所以如果你去看状态4,你会看到:
state 4
99 compound_statement: '{' . '}'
100 | '{' . statement_list '}'
IDENTIFIER shift, and go to state 6
:
IDENTIFIER [reduce using rule 1 (threat_as_ref)]
IDENTIFIER [reduce using rule 2 (func_call_start)]
Run Code Online (Sandbox Code Playgroud)
这告诉你,在这种状态下(解析a compound_statement,看过a {),并查看下一个令牌IDENTIFIER,它可以做3件事 - 转移令牌(这将是a的开头statement_list),减少threat_as_ref空生产,或减少func_call_start空产.
括号告诉您它已经决定永远不会执行这些操作 - 默认的"优先转移减少"冲突解决意味着它将始终执行转换.
用你的语法的问题是这些空规则threat_as_ref和func_call_start-他们需要转移前的标识会有所减少,但为了知道,如果他们是有效的,解析器需要看到的令牌IDENTIFER了. func_call_start如果这是函数调用的开始(这取决于(IDENTIFIER之后是否存在),那么只应该减少.所以解析器需要更多的前瞻来处理你的gramar.在你的特定情况下,你的语法是LALR(2)(2个令牌前瞻就足够了),但不是LALR(1),所以野牛不能处理它.
现在你可以通过删除那些空的规则来修复它 - func_call_start根本没有任何动作,并且threat_as_ref可以将动作移动到动作中variable,但是如果你希望将来这些规则可能是个问题.