考虑尝试LR语法,如下所示,其中引用的字符串被假定为终端符号:
S: E
E: ("y" | "z") X A
E: ("y" | "z") X B
X: "x"
X: X "x"
A: "a"
B: "b"
这似乎应该是一个无冲突的LR(1)语法,因为它等同于
S: E
E: ("y" | "z") X (A | B)
X: "x"
X: X "x"
A: "a"
B: "b"
然而,我认为(?)任何真实的解析器都会将其机械地转换为
S: E
E: U X A
E: V X B
U: "y"
U: "z"
V: "y"
V: "z"
X: "x"
X: X "x"
A: "a"
B: "b"
其中U
和V
是由其子句在解析树中直接替换的符号。
结果语法现在是LR(∞);它有减少 - 减少LR(k <∞)的冲突 - 尽管事实上它确实不应该![/ p>
现在,我意识到可以使这个例子更复杂(比如说,使用重复和分离);事实上,据我所知,检测到这种情况会减少测试两个无上下文语法的等价性,如果我没记错的话,这是一个不可判定的问题。
我的问题是:
我是否认为这是一个实际问题,或者我错过了一个实用的解决方案?
处理此问题的最佳方法是什么?报告冲突是最好的方式,还是在实践中使用启发式方法来解决问题?