我正在尝试使用LALR(1)解析器生成器解析一个简单的语法(Bison,但问题不是特定于该工具),而且我正在遇到一个shift-reduce冲突。我发现的关于修复这些内容的文档和其他来源倾向于说出以下一个或多个:
然而,这些似乎都不适用于我的情况:语法是明确无误的(尽管当然它只有一个前瞻性字符含糊不清),它只有一个操作符,默认分辨率导致解析正确形成的输入上的错误。是否有任何技术可以重新定义语法,以消除不属于上述存储桶的移位减少冲突?
具体来说,这是有问题的语法:
%token LETTER
%%
%start input;
input: /* empty */ | input input_elt;
input_elt: rule | statement;
statement: successor ';';
rule: LETTER "->" successor ';';
successor: /* empty */ | successor LETTER;
%%
目的是解析“[A-Za-z] +”或“[A-Za-z] - > [A-Za-z] +”形式的分号分隔行。
答案 0 :(得分:2)
使用Solaris版yacc
,我得到:
1: shift/reduce conflict (shift 5, red'n 7) on LETTER
state 1
$accept : input_$end
input : input_input_elt
successor : _ (7)
$end accept
LETTER shift 5
. reduce 7
input_elt goto 2
rule goto 3
statement goto 4
successor goto 6
因此,麻烦的是,通常是空的规则 - 特别是空的继任者。你是否想要允许分号作为有效输入还不是很清楚 - 目前,它是。如果您将后续规则修改为:
successor: LETTER | successor LETTER;
消除了转移/减少冲突。
答案 1 :(得分:0)
感谢您减少语法并发布。将后续规则更改为 -
successor: /* empty */ | LETTER successor;
......为我工作。 ITYM 语言看起来很明确。