当前位置: 首页 > 面试题库 >

是什么使Java比C更容易解析?

顾磊
2023-03-14
问题内容

为了使C解析起来更容易处理,您需要更改什么?

我之所以问是因为,我所见过的有关C的上下文敏感度的所有示例在技术上都是允许的,但非常奇怪。例如,

foo (a);

可能正在foo使用arguments
调用void函数a。或者,它可能声明a是type的对象foo,但您也可以轻松摆脱寄生。在某种程度上,这种怪异之所以会发生是因为C语法的“直接声明符”生成规则满足了声明函数和变量的双重目的。

另一方面,Java语法对变量声明和函数声明有单独的生产规则。如果你写

foo a;

那么您知道它是一个变量声明,foo可以明确地解析为类型名。如果foo尚未在当前作用域的某个位置定义该类,则这可能不是有效的代码,但这是语义分析的工作,可以在以后的编译器遍历中执行。

我已经看到它说C由于typedef很难解析,但是您也可以在Java中声明自己的类型。除了之外direct_declarator,还有哪些C语法规则有误?


问题答案:

解析C ++变得越来越困难。 解析Java变得同样困难。

看到这个SO答案,讨论为什么C(和C )“很难”解析。简短的摘要是C和C 语法
本质上是模棱两可的。它们将为您提供多个解析,并且您 必须
使用上下文来解决歧义。人们会犯这样的错误,即假设您必须在解析时解决歧义。不是,请参见下文。如果您在解析时坚持解决歧义,那么解析器将变得更加复杂且难以构建。但是这种复杂性是自我伤害。

IIRC,Java 1.4的“显而易见的” LALR(1)语法并不明确,因此解析起来“容易”。我不太确定现代Java至少不会在本地产生歧义。总是存在决定“

”是关闭两个模板还是“右移运算符”的问题。我怀疑现代Java不再使用LALR(1)进行解析

但是,对于这两种语言,都可以通过使用强解析器(或弱解析器和上下文收集黑客,因为C和C 前端现在大多这样做)来解决解析问题。C和C
具有预处理器的额外复杂性。在实践中,这些比看起来复杂得多。一种说法是,C和C ++解析器太难了,必须手动编写。 这不是真的
您可以使用GLR解析器生成器来构建Java和C ++解析器。

但是解析并不是问题所在。

解析后,您将需要对AST
/解析树进行操作。实际上,您需要知道每个标识符的定义以及定义的用途(“名称和类型解析”,草率地构建符号表)。事实证明,这比完成正确的解析器要花很多功夫,再加上继承,接口,重载和模板,所有这些语义都是用非正式的自然语言编写的,这分散了数十到数百个页面语言标准。C
++在这里真的很糟糕。从这个角度来看,Java 7和8变得非常糟糕。(而且符号表并不是您所需要的;请参阅我的html" target="_blank">简历,以获取有关“解析后的生活”的更长的文章)。

大多数人都在为纯解析部分而苦苦挣扎(通常永不完结;请检查SO本身是否有很多有关如何为实际语言构建解析器的问题),因此他们永远都看不到解析后的生命。然后,我们得到了关于难以解析的内容的民间定理,而没有任何关于该阶段之后发生的情况的信号。

修复C ++语法将无济于事。

关于更改C 语法:您会发现需要修补很多地方,以照顾任何C
语法中各种局部和实际的歧义。如果您坚持认为,以下列表可能是一个很好的起点。我认为,如果您不是C
标准委员会的成员,那么这样做是没有意义的。如果这样做,并使用该代码构建了编译器,那么没有人会理智地使用它。在现有的C
应用程序上投入了太多资金,无法切换以方便构建解析器的人员。此外,他们的痛苦已经过去,现有的解析器可以正常工作。

您可能要编写自己的解析器。好没关系;
只是不要期望社区中的其他人能够让您更改他们必须使用的语言以使其更容易使用。他们都希望对他们来说更容易,那就是使用已记录和实现的语言。



 类似资料:
  • 本文向大家介绍什么是PEAR?什么是PECL?PHP中两个容易混淆的概念解释,包括了什么是PEAR?什么是PECL?PHP中两个容易混淆的概念解释的使用技巧和注意事项,需要的朋友参考一下 概述 关于PEAR,PECL这两个东西,初学PHP的时候就知道,但是貌似用的人很少再加上以前也是在Windows下做开发,所以了解的不多,现在转到Mac了,就把这两个东西彻底弄弄清楚。 什么是PEAR PEAR的

  • 我是移动开发的新手,我看到ionic framework有很大的社区,但是 我知道ionic使用webview,而nativescript生成本地组件 我现在的问题是什么nativescript可以做离子不能做? 换句话说,nativescript中有哪些在爱奥尼亚没有的强大之处 提前谢谢。

  • 问题内容: 我目前正在决定要在其上构建科学计算产品的平台,并且正在决定在Core2 Quad CPU上使用C#,Java或带有Intel编译器的纯C语言。它主要是整数运算。 到目前为止,我的基准测试表明Java和C彼此差不多,并且.NET / C#落后大约5%,但是我的许多同事都声称经过适当的优化的.NET将在足够的时间上击败这两个方面。供JIT开展工作。 我一直以为JIT会在应用启动后的几分钟内

  • > 我看到接口只允许实现方法。那么为什么我们甚至需要这个接口呢?为什么我们不能简单地在我们想要的任何类中定义和声明该方法,而无需实现接口? 我知道这是正确的:

  • 问题内容: 因此,我刚刚意识到反编译Java代码是多么容易。我一直在网上搜索,但似乎无法弄清楚 为什么 这么容易。每次我在Google上搜索“为什么要反编译文件?”之类的信息时,或“为什么Java这么容易反编译”,我所得到的只是指向可以轻松反编译我的代码的软件的链接。因此,我向您介绍StackOverflow:为什么Java可以转换回容易阅读的源代码,而C ++和其他语言对反编译不是很友好? 谢谢

  • Java: 如果java以微弱优势击败了C和C#我不会感到惊讶,但速度快了20倍?! 文件的格式如下: 另外,我认为值得注意的是,java在NetBeans中运行时大约需要11秒(即使是在“运行”模式下,而不是在“调试”模式下)。 我也尝试编译为C++而不是C,但没有什么不同。 我对C和C#都使用VS2015。 Java: 好吧,我按照建议重新做了测试: 首先,我在C和C#中都使用了类/struc