c#和Java语法都是LALR(x)

本文关键字:LALR Java 语法 | 更新日期: 2023-09-27 18:16:49

我想知道如果c#和Java语法是LALR(x)?如果是,x的值是多少?

编辑:

在接受真实答案后,我认为最好这样改变Q:

是否有可以解析当前版本的Java (version 7)或c# (version 4)的LALR(x)解析器?如果是,x的值是多少?

c#和Java语法都是LALR(x)

如果不首先为一种语言指定特定的语法,就不能问这个问题,因为有些语法可能是,有些可能不是。

也许您指的是在最近的Java规范中发布的Java语法。你是说Java 7吗?

我不确定你可以为c#指定一个特定的语法,至少没有一个来自微软,特别是c# 4.0;我不相信他们已经发表了语法。

我可以告诉你我不认为c#可以是LALR(x),因为它有一些元素看起来像标识符,但在某些上下文中可以是关键字。这要求词法分析器知道解析器期望什么,以确定类似标识符的令牌是关键字,还是只是一个标识符。因此,必须有从解析器到词法分析器的反馈,或者词法分析器必须生成两个令牌并将它们传递给解析器以决定需要哪个。LALR解析器是在没有任何反馈的令牌流上定义的,并且每个输入令牌只有一种解释。

enum作为带有自己关键字的特殊类型引入时,我也不认为Java是从Java 1.5及以上开始的。这是因为,对于Java 1.5编译器来说,要处理使用enum作为变量名的现有Java 1.4程序,enum必须在某些上下文中被视为关键字,而在其他上下文中被视为变量名。因此,Java 1.5解析器存在与c#相同的问题。

作为一个实际问题,没有真正的语言是LALR(1)[第一版Java可能是个例外],任何构建真正的解析器(尤其是LALR)的人都必须做一些hack来绕过这个问题。(很长一段时间以来,GCC都是用LALR解析器解析c++的,它使用了一个糟糕的符号表hack,所以它可以区分作为变量的标识符和作为类型定义实例的标识符。它现在有某种手工实现的递归下降解析器,但我认为糟糕的hack仍然存在)。所以我不确定回答你的问题的价值。

我们的语言前端家族中的c# 4.0和Java 7成员都使用GLR解析器解析语言,扩展了反馈功能,并能够处理同一令牌的两种解释。GLR使LALR(x)的问题变得没有意义,并且反馈和多种解释使我们能够处理纯GLR能力之外的许多语言。

编辑:经过一番思考,可能有一种真正丑陋的方法来让两个语法处理上下文中的关键字。让我们以Java的枚举为例。实际上必须有语法规则:

  type = 'enum' '{'  enum_members '}' ;

但是我们还需要允许'enum'作为标识符。我们可以通过替换终端令牌来做到这一点标识符带非终结符:

  identifier = IDENTIFIER | 'enum' ;

并坚持标识符是词法分析器生成的终端。现在至少词法分析器不必决定如何处理enum;解析器会这样做。但是,您指定的语法必须像这样形成,以便有机会成为LALR(x)。

我们的解析器过去这样做是为了允许某些关键字有时用作标识符。我们按照前面的描述更改了解析引擎,现在不再这样做了。

Java语法(1.0版本)已知为LALR(1);该站点提供语法,并以

的通知开头

语法已经过机械检查,以确保它是LALR(1)。

我不确定c#是否为LALR(1),但这里有一个用bison编写的c#解析器,这表明它可能是LALR(1)(假设您允许优先级声明)。

无论如何,通常LALR(1)是唯一使用的LALR解析器。如果您需要为语法使用类似LALR(2)的东西,通常使用具有显式优先级消歧的LALR(1)解析器或更强大的解析器(如GLR解析器)是更好的主意。

希望这对你有帮助!

至少对于Java(1.0版本)是:http://java.sun.com/docs/books/jls/first_edition/html/19.doc.html