我正在尝试使用 LALR(1) 解析器生成器(Bison,但问题并非特定于该工具)解析一个简单的语法,并且我遇到了 shift-reduce 冲突。我发现的有关修复这些问题的文档和其他资源往往会说以下一项或多项:
- 如果语法有歧义(例如 if-then-else 歧义),请更改语言以修复歧义。
- 如果是运算符优先级问题,请明确指定优先级。
- 接受默认分辨率并告诉生成器不要抱怨它。
然而,这些似乎都不适用于我的情况:据我所知,语法是明确的(当然它只有一个前瞻字符是模棱两可的),它只有一个运算符,默认分辨率会导致解析错误在正确格式的输入上。是否有任何技术可以重新定义语法以消除不属于上述存储桶的移位减少冲突?
具体而言,这是有问题的语法:
%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]+”形式的分号分隔的行。