如何解决移位/归约冲突?

13

我正在使用CUP创建一个我论文所需的解析器。我的语法中存在移进/规约冲突。我有这个产生式规则:

command ::= IDENTIFIER | IDENTIFIER LPAREN parlist RPAREN;

我有这个警告:

Warning : *** Shift/Reduce conflict found in state #3
between command ::= IDENTIFIER (*) 
and     command ::= IDENTIFIER (*) LPAREN parlist RPAREN 
under symbol LPAREN

现在,我实际上想让它移位,所以我对此很满意,但我的教授告诉我要找到解决冲突的方法。我是盲人。我一直听说过if/else冲突,但对我来说似乎不是这种情况。你能帮帮我吗?

P.S .:IDENTIFIER,LPAREN“(”和RPAREN“)”是终端,parlist和command不是。

3个回答

11
你的问题根本不在那些规则中。虽然Michael Mrozek的答案是解决“悬挂else问题”的正确方法,但它并没有抓住实际问题所在。
如果你看一下错误消息,你会发现移位/归约冲突存在于词法分析LPAREN时。我很确定仅凭规则是不会产生冲突的。
我看不到你的语法,所以无法帮助你。但你的冲突可能是当一个“command”后跟着不同的以“LPAREN”开头的规则时。
查看任何其他可能跟在“command”后面且以“LPAREN”开头的规则。然后,你将不得不合并这些规则。你的语法很有可能对特定的输入有误。

是的,你说得对。问题出在这一行的上面。我已经在4天前解决了这个问题。我忘记更新问题了。 - dierre

9

您有两个产品:

command ::= IDENTIFIER
command ::= IDENTIFIER LPAREN parlist RPAREN;

当输入标记为IDENTIFIER LPAREN时,存在一种移位/归约冲突,因为:
  • LPAREN可能是您未列出的新产生式的开头,在这种情况下,解析器应将堆栈中的IDENTIFIER归约为command,并保留command LPAREN
  • 它们都可能是第二个产生式的开头,因此它应该将LPAREN移位到IDENTIFIER旁边的堆栈上,并继续读取,尝试找到parlist
您可以通过执行以下操作来修复它:
command ::= IDENTIFIER command2
command2 ::= LPAREN parlist RPAREN |;

谢谢,但即使使用这个解决方案,我仍然遇到相同的移位/规约冲突。我没有语法错误,所以我很确定CUP没有使用一些奇怪的“空符号”,但我正在检查它。 - dierre

1
尝试设置一个优先级:
precedence left     LPAREN, RPARENT;

它强制CUP决定冲突,选择左侧匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接