注意:这个问题不是关于“Java 没有指针”
在 C 语言中,代码 identifier1 *identifier2
对于两种可能的含义是不明确的:
- 如果标识符1是类型,那么这可能是指针声明。
- 如果标识符1是一个变量,那么这可能是一个乘法语句。
问题是我在构建语法树时无法选择正确的产生式。我检查了 Clang 的代码,看来 Clang 必须将类型检查(通过使用符号表)放到解析阶段(如果我错了,请纠正我)。
然后我检查了javac(OpenJDK)的代码,似乎在解析阶段,没有涉及语义分析。解析器几乎不需要使用 token 就可以构建 AST。
所以我很好奇Java是否也有同样的歧义语法问题?如果解析器不知道标识符的类型,则无法选择正确的产生式的问题?
或更通用的是,Java 是否存在语法歧义,以至于解析器无法在没有 token 流以外的其他信息的情况下选择产生式?
最佳答案
对于语言来说,标记化始终是上下文相关的。然而,Java 没有这么敏感的运算符。然而,您可以以这样的方式链接标记,这会产生歧义,但不仅仅是作为更大语法语句的一部分:
A < B
可以是 public class A < B > { ... }
的一部分或if (A < B) { ... }
。
第一个是通用类定义,第二个是比较。
这只是我的第一个例子,但我想还有更多。
然而,运算符的定义通常非常狭窄,并且不能(如在类似 C/C++ 的语言中)重载。此外,除了 C/C++ 之外,只有一个访问操作符(点: .
),但有一个异常(exception)(从 Java 8 开始,为双冒号 ::
)。
在 C++ 中,有很多,所以不那么困惑。
关于 Java 是否始终在语法上可判定的具体问题: 是的。一个实现良好的编译器总是可以根据 token 流来决定存在什么 token 。
关于java - Java 是否有不明确的语法,需要有关标识符的更多信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55567729/