C#和Java语法是LALR(x)吗?

时间:2011-12-04 20:55:57

标签: c# java parsing lalr

我想知道C#和Java语法是否是LALR(x)?如果是,x的值是什么?

修改

在接受了真正的答案后,我认为以这种方式改变Q更好:

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

3 个答案:

答案 0 :(得分:14)

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

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

我不确定你能为C#指定一个特定的语法,至少不是微软的一个,特别是对于C#4.0;我不相信他们已经发表了语法。

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

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

实际上,没有真正的语言是LALR(1)[第一版Java可能是一个例外]并且构建真正的解析器(尤其是LALR)的任何人都必须做出某种破解来解决这个问题。 (海湾合作委员会着名地用一个LALR解析器解析了C ++,其中很长一段时间都是一个糟糕的符号表黑客,因此它可以区分作为变量的标识符和作为typedef实例的标识符。它现在有一些手工实现递归下降解析器,但我认为可怕的黑客仍然存在)。所以我不确定回答你问题的价值。

我们的C# 4.0 and Java 7 members of our family of language front ends都使用GLR解析器解析语言,扩展了反馈功能,并能够处理同一令牌的两种解释。 GLR使LALR(x)的问题没有实际意义,反馈和多种解释使我们能够处理许多超出纯GLR能力的语言。

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

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

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

  identifier = IDENTIFIER | 'enum' ;

并坚持认为IDENTIFIER是词法分析器生成的终端。现在至少lexer不必决定如何对待 enum ;解析器。但是你的指定语法必须像这样形成,以便有机会成为LALR(x)。

我们的解析器过去常常允许某些关键字有时用作标识符。我们如前所述更改了解析引擎,不再这样做了。

答案 1 :(得分:13)

Java语法(版本1.0)已知为LALR(1); this site提供语法,并以

的通知开头
  

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

我不确定C#是否是LALR(1),但这里有一个C# parser written in bison,这表明它可能是LALR(1)(假设您允许优先声明)。

对于它的价值,通常LALR(1)是唯一使用的LALR解析器。如果您需要使用类似LALR(2)的语法,那么使用具有明确优先级消歧的LALR(1)解析器或更强大的解析器(如GLR解析器)通常更好。

希望这有帮助!

答案 2 :(得分:4)

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