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

时间:2016-11-05 10:25:54

标签: parsing compiler-construction bison lalr shift-reduce-conflict

我正在Bison中为一种语言编写解析器,该语言具有以下结构:

  • 自行发送:[identifier arguments]
  • 发送:[expressionidentifier arguments]
  • 字符串切片:expression [expressionexpression] - 与Python类似。

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

更准确地说,让我们采用以下示例:[a[b]](使用方法a的结果调用方法b。当它到达状态[a时。 [b]](前瞻是第二个[),它不知道是否将a(已经减少到identifier)减少到expression因为a[b,c]之类的内容可能会跟随(它本身可以缩减为expression并继续使用上面的第二个结构)或保留identifier(并转移它),因为arguments列表{ {1}}将会跟随(例如,在这种情况下为[b])。

这种转移/减少冲突是由于我表达这种语法的方式还是不可能用LALR(1)解析器解析所有这些结构?

而且,更一般的问题是,如何证明某种语言不能被特定类型的解析器解析?

1 个答案:

答案 0 :(得分:2)

假设您的语法是明确的(您描述的部分似乎是),那么您最好的选择是指定%glr-parser。由于在大多数情况下,只需几个令牌就会强制执行正确的解析,因此开销不应太明显,并且优点是您不需要使语法或AST的构造复杂化。

一个缺点是,野牛无法验证语法是否明确 - 通常,这是不可能的 - 并且不容易证明。如果事实证明某些输入是不明确的,那么GLR解析器将产生错误,因此一个好的测试套件很重要。

证明语言不是LR(1)会很棘手,我怀疑它是不可能的,因为语言可能是可识别的与LALR(1)解析器。 (但是不可能在没有看到整个语法的情况下告诉。)但是解析(在CS理论之外)需要创建一个正确的解析树才能有用,并且产生LR语法所需的那种修改也将修改AST ,需要一个解析后的修正。

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

[a[b[c],d]]

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

由于“优先级”不能正式定义,所以有点手动,并且有一些黑客可以调整树。由于LR属性不是真正可组合的,因此可以提供更严格的分析。但无论如何,GLR解析器可能是最简单和最强大的解决方案。

未来参考的一个小问题:CFG不仅仅是一种编程工具;它们还有助于清楚地传达有关语法。 Nirmally,如果你想描述你的语言,你最好使用一个明确的CFG,而不是试图非正式地描述。当然,有意义的非终端名称会有所帮助,而且一些例子从未受到伤害,但语法的本质在于正式描述和省略,这使得其他人更难以“有所帮助”。