LR(k) 到 LR(1) 语法转换

2024-04-08

我对以下内容感到困惑quote http://en.wikipedia.org/wiki/LR_parser#Theory来自维基百科:

换句话说,如果一种语言足够合理,允许 高效的单遍解析器,可以用 LR(k) 语法来描述。 语法总是可以机械地转化为 等效(但更大)的 LR(1) 语法。所以 LR(1) 解析方法是, 理论上,它足够强大来处理任何合理的语言。在 实践中,许多编程语言的自然语法是 接近 LR(1)。[需要引用]

这意味着解析器生成器,例如bison,非常强大(因为它可以处理LR(k)语法),如果能够将LR(k)语法到LR(1)语法。是否存在一些这样的例子,或者如何做到这一点的秘诀?我想知道这一点,因为我的语法中有移位/归约冲突,但我认为这是因为它是LR(2)语法并想将其转换为LR(1)语法。附带问题:是C++一种不合理的语言,因为我读过,bison- 生成的解析器无法解析它。


有关寻找覆盖的通用算法的参考LR(1)语法为LR(k)语法,参见现实世界的 LR(k > 1) 语法? https://stackoverflow.com/questions/20207339/real-world-lrk-1-grammars/20208748#20208748

通用算法产生相当大的语法;事实上,我非常确定最终的 PDA 与LR(k)PDA 就可以了。然而,在特定情况下,可以提出更简单的解决方案。不过,一般原则是适用的:您需要通过无条件移位来推迟移位/归约决策,直到可以使用单个前瞻标记做出决策。

一个例子:C#的lambda表达式语法是LALR(1)吗? https://stackoverflow.com/questions/16928725/is-cs-lambda-expression-grammar-lalr1/16931641#16931641

在不了解有关语法的更多详细信息的情况下,我无法提供更多帮助。

对于 C++,使解析变得棘手的是预处理器和解析(和词法分析)模板实例化中的一些极端情况。事实上,表达式的解析取决于符号的“种类”(而不是类型)(在符号出现的上下文中),这使得使用 bison 进行精确解析变得复杂。 [1] “不合理”是一种我不愿意做出的价值判断;当然,使用不同的语法,工具支持(如准确的语法着色器和制表符完成器)会很简单,但证据表明编写(甚至阅读)好的 C++ 代码并不难。


Notes:

[1] 经典的棘手解析,也适用于 C,是(a)*b,这是取消引用的强制转换 ifa表示类型,否则表示乘法。如果你要在上下文中写它:c/(a)*b,很明显,如果不知道它是铸件还是产品,就无法构建 AST,因为这会影响 AST 的形状,

一个更具体的 C++ 问题是:x<y>(z) (or x<y<z>>(3))根据是否进行不同的解析(并且可以说是标记化)x是否命名模板。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LR(k) 到 LR(1) 语法转换 的相关文章