【发布时间】:2016-02-24 09:36:56
【问题描述】:
我为 C++17 编写了一个 LALR(1) 解析器。我发现了156个歧义,其中一些我可以按照标准解决,但其他我不能。
例如: 当遇到 小于 时,在解析“operator+ ”时会发生 Shift-Reduce 冲突:
我们可以将其解析为:
(1)
template-id -> operator-function-id ·
或:
(2)
unqualified-id -> operator-function-id · 其中 (1) 需要转移,但 (2) 需要减少。
但是,标准有:
在名称查找 (3.4) 后发现名称是模板名称,或者 operator-function-id 或literaloperator-id 引用一组重载函数,其中任何成员都是函数模板,如果后面跟着一个 137 被视为结束分隔符,而不是大于运算符。
所以我们选择换班。
不幸的是,有很多模棱两可的地方我找不到解决办法。在这里我列出了其中的一些(其中一些可以清楚地做出选择,但我就是找不到证据):
- 标准中是否有某些部分表明当出现歧义时“移位”是默认选择?
声明符
(1)当一个noptr-declarator被解析,遇到一个left-paren时,我应该按照:
ptr-declarator -> noptr-declarator ·
或移动左括号以满足:
declarator -> noptr-declarator · 参数和限定符
parameters-and-qualifiers -> · left-paren parameter-declaration-clause right-paren......
(2)当解析一个declarator-id遇到左括号时,我应该按照:
noptr-declarator -> declarator-id · noptr-declarator -> noptr-declarator · \left-bracket ?constant-expression \right-bracket ?attribute-specifier-seq
或左移满足:
noptr-declarator -> declarator-id ·attribute-specifier-seq
(attribute-specifier-seq is [[.......]])
【问题讨论】:
-
我上次查看是在 1990 年代,C++ 语法有 53 个移位归约冲突,如果我没记错的话,还有一些归约冲突。
-
C++ 标准没有任何地方说该语法是 LARL(1) 语法。它也没有描述你打算如何实现解析器。
-
众所周知,语法不能用la LALR解析,那么您期望或想要什么?