Bison语法偶尔会通过,偶尔会失败

时间:2014-09-21 20:30:16

标签: grammar bison shift-reduce-conflict

我第一次与Bison语法广泛合作。我设置了语法,并设置了一个关联结果的小测试套件。

有时,测试套件会通过:

Reducing stack by rule 101 (line 613):
   $1 = nterm mathenv ()
-> $$ = nterm closedTerm ()
Stack now 0 5 3
Entering state 120
Reading a token: Next token is token ENDMATH ()
Reducing stack by rule 28 (line 517):
   $1 = nterm closedTerm ()
-> $$ = nterm compoundTerm ()
Stack now 0 5 3
Entering state 119
Reducing stack by rule 12 (line 333):
   $1 = nterm compoundTerm ()
-> $$ = nterm compoundTermList ()
Stack now 0 5 3
Entering state 198
Next token is token ENDMATH ()
Shifting token ENDMATH ()
Entering state 325

... continues to completion ...

偶尔也不会:

Reducing stack by rule 101 (line 613):
   $1 = nterm mathenv ()
-> $$ = nterm closedTerm ()
Stack now 0 5 3
Entering state 120
Reading a token: Next token is token MN ()
Reducing stack by rule 28 (line 517):
   $1 = nterm closedTerm ()
-> $$ = nterm compoundTerm ()
Stack now 0 5 3
Entering state 119
Reducing stack by rule 12 (line 333):
   $1 = nterm compoundTerm ()
-> $$ = nterm compoundTermList ()
Stack now 0 5 3
Entering state 198
Next token is token MN ()
Shifting token MN ()
Entering state 11

... errors eventually ...

Now at end of input.
Line: 9 Error: syntax error at token 

ENDMATH是要转移到的正确令牌,但有时会确定MN。每当我运行测试时,我都会得到不一致的结果。这种“随机”歧义是否正常?可能是什么原因造成的?我应该定义一些%precedence规则吗?

y.output 的顶部,我确实看到了状态的几个冲突,比如

State 0 conflicts: 3 shift/reduce
State 120 conflicts: 2 shift/reduce
State 127 conflicts: 2 shift/reduce
State 129 conflicts: 2 shift/reduce
State 154 conflicts: 1 shift/reduce
State 207 conflicts: 3 shift/reduce
State 265 conflicts: 109 shift/reduce
State 266 conflicts: 109 shift/reduce
State 267 conflicts: 109 shift/reduce
State 268 conflicts: 109 shift/reduce
State 269 conflicts: 109 shift/reduce
State 342 conflicts: 2 shift/reduce
State 390 conflicts: 109 shift/reduce
State 391 conflicts: 109 shift/reduce
State 396 conflicts: 1 shift/reduce
State 397 conflicts: 1 shift/reduce

消除所有这些冲突是否明智?请注意,状态120被列为具有冲突,并且是发生此随机错误之前的状态。

1 个答案:

答案 0 :(得分:2)

你的语法冲突意味着语法不是LALR(1)。这可能是由于语法不明确或者可能是由于语法需要多个前瞻标记。每当你遇到冲突时,野牛就会根据你拥有的优先指令选择一个可能的动作(移位或缩小)来解决它。这导致解析器识别(解析)语法描述的语言的某些子集。

如果冲突纯粹是由于歧义,这可能导致只是消除模棱两可的解析,而不是实际上减少语言。对于这种情况,使用优先级规则来解决歧义是处理问题的正确方法,因为它为您提供了解析所需语言的语法。

如果冲突是由于需要更多前瞻,优先规则通常没有帮助。您需要通过重新排列语法以不需要前瞻或使用其他技术(黑客)来解决问题,例如让词法分析器根据输入或其他信息中的进一步前瞻插入额外的合成令牌。

在你的情况下,直接问题似乎在词法分析器中 - 如果它返回令牌ENDMATH而在另一个中它返回MN。在与y.output中看到的冲突相关的语法中可能存在含糊不清或前瞻性问题,但这些问题乍一看似乎完全独立于词法分析器的问题。