这可以被 LALR(1) 解析器解析吗?

Can this be parsed by a LALR(1) parser?

我正在用 Bison 为一种具有以下构造的语言编写解析器:

arguments 是逗号分隔的表达式列表,也可以为空。以上所有内容也是它们自己的表达方式。 我的问题是我不确定如何解析 [method [other_method]][someString[idx1, idx2].toInt],或者是否可以使用 LALR(1) 解析器完全解析。

更准确地说,让我们来看下面的例子:[a[b]](调用方法a,方法b的结果)。当它到达状态 [a 时。 [b]](lookahead是第二个[),不知道是否要将a(已经缩减为identifier)缩减为expression因为 a[b,c] 之类的东西可能会跟随(它本身可以减少到 expression 并继续上面的第二个构造)或保留它 identifier (并移动它)因为列表 arguments 将跟随(例如本例中的 [b])。

这种 shift/reduce 冲突是由于我表达此语法的方式造成的,还是无法使用 LALR(1) 解析器解析所有这些结构?

还有一个更普遍的问题,如何证明一种语言 is/is 不能被特定类型的解析器解析?

假设你的语法是明确的(你描述的部分似乎是)那么你最好的选择是指定一个 %glr-parser。因为在大多数情况下,正确的解析将在几个标记之后被强制执行,开销应该不会很明显,优点是您不需要使语法或 AST 的构造复杂化。

一个缺点是 bison 无法验证语法是否无歧义——一般来说,这是不可能的——而且不容易证明。如果发现某些输入不明确,GLR 解析器将产生错误,因此一个好的测试套件很重要。

证明该语言不是 LR(1) 会很棘手,我怀疑这是不可能的,因为该语言可能 可识别 具有 LALR(1) 解析器. (不过,如果不看整个语法就无法判断。)但是解析(在 CS 理论之外)需要创建一个正确的解析树才能有用,并且生成 LR 语法所需的修改类型也会修改 AST ,需要 post-parse 修正。从

之间的优先级差异创建正确的 AST spring 的困难
a[b[c],d]

[a[b[c],d]]

在第一个(子集)情况下,b 绑定到它的参数列表 [c] 并且逗号具有较低的优先级;最后,b[c]d 是该切片的兄弟姐妹。在第二种情况(方法调用)中,逗号是参数列表的一部分,并且比方法应用程序绑定得更紧密; b[c]d 是方法应用程序中的兄弟。但是在任意长的输入之前你不能决定解析树的形状(因为 d 可以是任何表达式)。

由于 "precedence" 无法正式定义,所以这有点手忙脚乱,并且有一些 hack 可以调整树。由于LR 属性 不是真正可组合的,因此确实可以提供更严格的分析。但无论如何,GLR 解析器可能是最简单、最可靠的解决方案。

一点供日后参考:CFG不仅仅是一种编程工具;它们还有助于清楚地传达所讨论的语法。通常,如果您想描述您的语言,最好使用清晰的 CFG,而不是试图非正式地描述。当然,有意义的非终结符名称会有所帮助,并且一些示例也无妨,但语法的本质在于正式描述和省略,这使得其他人更难 "be helpful".