是什么让Java比C更容易parsing?

我熟悉C和C ++的语法是上下文敏感的 ,特别是你需要在C中使用“词法分析器”。另一方面,我的印象是,你可以只用Java来parsing尽pipe这两种语言之间有相当的相似性,但它们还是有前瞻性的。

你需要改变一些关于C来使它更容易parsing的东西?

我问,因为所有我看过的关于C语境的例子在技术上是可以允许的,但是很奇怪。 例如,

foo (a); 

可以用参数a调用void函数foo 。 或者,它可以被声明a footypes的一个对象,但是你可以轻松地摆脱这些缺点。 部分原因是由于C语法的“直接声明者”生成规则实现了声明函数和variables的双重目的,所以出现了这种怪异现象。

另一方面, Java语法对于variables声明和函数声明分别具有生产规则。 如果你写

 foo a; 

那么你知道这是一个variables声明,而且foo可以毫不含糊地被parsing为一个types名称。 如果foo类没有在当前作用域的某个地方被定义,那么这可能不是有效的代码,但是这是语义分析的一个工作,可以在稍后的编译器中执行。

我已经看到它说C因为typedef很难parsing,但是你也可以在Java中声明你自己的types。 除了direct_declarator之外,哪些C语法规则是错误的?

parsingC ++越来越困难。 parsingJava变得同样困难。

看到这个回答讨论为什么C(和C ++)是“难”parsing 。 简而言之,C和C ++ 语法本质上是不明确的; 他们会给你多个parsing,你必须使用上下文来解决歧义。 然后,人们认为在parsing时必须解决含糊不清的错误; 不是这样,见下文。 如果您在parsing时坚持要解决歧义问题,那么parsing器就会变得更加复杂,而且难于构build。 但这种复杂性是一种自我伤害。

IIRC,Java 1.4的“显而易见的”LALR(1)语法并不含糊,所以parsing起来很“容易”。 我不太确定,现代Java没有至less有长距离的地方歧义; 总是会有决定“… >>”是closures两个模板还是“右移运算符”的问题。 我怀疑现代Java不再与LALR(1)parsing 。

但是,对于这两种语言,我们可以通过使用强parsing器(或弱parsing器和上下文集合攻击,因为C和C ++前端大部分都是现在这样做)来解决parsing问题。 C和C ++有一个预处理器的额外复杂性; 这些在实践中比看起来更复杂。 有一种说法是,C和C ++parsing器非常辛苦,必须手工编写。 这不是真的; 您可以使用GLRparsing器生成器来构buildJava和C ++parsing器。

但是parsing并不是真正的问题所在。

一旦你parsing,你会想要做一些AST /parsing树。 实际上,对于每个标识符,您需要知道它的定义和使用位置(“名称和typesparsing”,斜坡,构build符号表)。 事实certificate,这比parsing器正确得多,通过inheritance,接口,重载和模板复杂化,以及所有这些语义都以非正式自然语言编写的语义跨越数十页到数百页的语言标准。 C ++在这里真的很糟糕。 从这个angular度来看,Java 7和8已经变得非常糟糕了。 (符号表并不是你所需要的;查看我的生物关于“parsing后的生活”的更长的文章)。

大多数人与纯粹的parsing部分斗争(通常永远不会完成;检查SO本身的许多问题,关于如何build立真正的langauges工作分析器),所以他们永远不会看到分析后的生活。 然后我们得到关于什么是难以parsing的民间定理,并没有关于在这个阶段后发生的信号。

修复C ++语法不会让你任何地方。

关于改变C ++语法:你会发现你需要修补很多地方来处理任何C ++语法中的各种本地和真实的歧义。 如果你坚持, 下面的列表可能是一个很好的起点 。 如果你不是C ++标准委员会,我认为这样做是毫无意义的。 如果你这样做,并build立一个编译器,没有人会理智的使用它。 现有的C ++应用程序投入太多,为了方便构buildparsing器的人员而进行切换; 此外,他们的痛苦已经结束,现有的parsing器正常工作。

你可能想写你自己的parsing器。 好没关系; 只是不要指望社区的其他人让你改变他们必须使用的语言,以使你更容易。 他们都希望他们更容易,那就是使用语言logging和实施。