Java 7 语法中的分隔标识符可以简化为限定标识符吗?
Can separated identifiers in the Java 7 grammar be reduced to qualified identifiers?
Java 7 syntax specification 指定一个 QualifiedIdentifier
,其中包含:
QualifiedIdentifier:
Identifier { . Identifier }
虽然在语法的后面部分,这个结构再次出现而不是限定标识符:
ImportDeclaration:
import [static] Identifier { . Identifier } [. *] ;
Primary:
Identifier { . Identifier } [IdentifierSuffix]
为什么要这样明确列出这些部分?不能简单地简化为:
ImportDeclaration:
import [static] QualifiedIdentifier [. *] ;
Primary:
QualifiedIdentifier [IdentifierSuffix]
唯一正确的语法
首先,请了解您引用的语法(JLS 7 第 18 章)实际上并不是 "The Java 7 syntax specification"(例如唯一正确的语法)。它是描述 Java 7 语法的 语法 。还有其他的,包括同一 JLS 文档前几章中的那个。 JLS 本身在 section 2.3, The Syntactic Grammar:
中阐明了这一点
A syntactic grammar for the Java programming language is given in Chapters 4, 6-10, 14, and 15. This grammar has tokens defined by the lexical grammar as its terminal symbols. It defines a set of productions, starting from the goal symbol CompilationUnit (§7.3), that describe how sequences of tokens can form syntactically correct programs.
Chapter 18 also gives a syntactic grammar for the Java programming language, better suited to implementation than exposition. The same language is accepted by both syntactic grammars.
并且Chapter 18的介绍解释了其中介绍的语法专门用于参考实现:
The grammar presented piecemeal in the preceding chapters (§2.3) is much better for exposition, but it is not well suited as a basis for a parser. The grammar presented in this chapter is the basis for the reference implementation.
所以没有单一规范Java语法。只有语言语法本身,可以用多种语法来表示。
建议的替代方案是否可以接受?
OP 询问是否
ImportDeclaration:
import [static] QualifiedIdentifier [. *] ;
Primary:
QualifiedIdentifier [IdentifierSuffix]
没问题。是的,当然,为什么不呢?描述的是同一种语言,肯定没问题。
那么他们为什么要这样做呢?
回想一下,第 18 章语法的目的是作为参考实现的基础。如果你仔细观察,你会发现 QualifiedIdentifier
在完全描述它所代表的 "Identifier-like construct"(我发明的术语)的地方一直被使用,而不是在它只是更大的 [=] 的一部分的地方67=].
查看 ImportDeclaration
,很明显可选的尾随 .*
是所导入事物的标识符 的一部分。在像 import java.util.*;
这样的导入中,java.util
部分虽然以点分隔,但并不是真正的限定标识符。表示正在导入的事物的类似标识符的结构是整个短语 java.util.*
。所以 认为 将其作为 QualifiedIdentifier
加上可选的 .*
有点让人头疼。
类似的论点可用于 Primary
。
此外,在 Import
或 Primary
中使用 QualifiedIdentifier
可能 会使解析器更加复杂。 (我很高兴听到真正的语言设计者对这个问题的看法。)换句话说,由于第 18 章的语法更适合实现,我不得不认为这个选择是经过深思熟虑的,并且使实现更容易。
底线
当然,上面给出的 QualifiedIdentifier
的建议用法在严格机械意义上描述了相同的语言。但是更喜欢书面语法有语义上的原因,也可能有实现上的原因。
Java 7 syntax specification 指定一个 QualifiedIdentifier
,其中包含:
QualifiedIdentifier:
Identifier { . Identifier }
虽然在语法的后面部分,这个结构再次出现而不是限定标识符:
ImportDeclaration:
import [static] Identifier { . Identifier } [. *] ;
Primary:
Identifier { . Identifier } [IdentifierSuffix]
为什么要这样明确列出这些部分?不能简单地简化为:
ImportDeclaration:
import [static] QualifiedIdentifier [. *] ;
Primary:
QualifiedIdentifier [IdentifierSuffix]
唯一正确的语法
首先,请了解您引用的语法(JLS 7 第 18 章)实际上并不是 "The Java 7 syntax specification"(例如唯一正确的语法)。它是描述 Java 7 语法的 语法 。还有其他的,包括同一 JLS 文档前几章中的那个。 JLS 本身在 section 2.3, The Syntactic Grammar:
中阐明了这一点A syntactic grammar for the Java programming language is given in Chapters 4, 6-10, 14, and 15. This grammar has tokens defined by the lexical grammar as its terminal symbols. It defines a set of productions, starting from the goal symbol CompilationUnit (§7.3), that describe how sequences of tokens can form syntactically correct programs.
Chapter 18 also gives a syntactic grammar for the Java programming language, better suited to implementation than exposition. The same language is accepted by both syntactic grammars.
并且Chapter 18的介绍解释了其中介绍的语法专门用于参考实现:
The grammar presented piecemeal in the preceding chapters (§2.3) is much better for exposition, but it is not well suited as a basis for a parser. The grammar presented in this chapter is the basis for the reference implementation.
所以没有单一规范Java语法。只有语言语法本身,可以用多种语法来表示。
建议的替代方案是否可以接受?
OP 询问是否
ImportDeclaration:
import [static] QualifiedIdentifier [. *] ;
Primary:
QualifiedIdentifier [IdentifierSuffix]
没问题。是的,当然,为什么不呢?描述的是同一种语言,肯定没问题。
那么他们为什么要这样做呢?
回想一下,第 18 章语法的目的是作为参考实现的基础。如果你仔细观察,你会发现 QualifiedIdentifier
在完全描述它所代表的 "Identifier-like construct"(我发明的术语)的地方一直被使用,而不是在它只是更大的 [=] 的一部分的地方67=].
查看 ImportDeclaration
,很明显可选的尾随 .*
是所导入事物的标识符 的一部分。在像 import java.util.*;
这样的导入中,java.util
部分虽然以点分隔,但并不是真正的限定标识符。表示正在导入的事物的类似标识符的结构是整个短语 java.util.*
。所以 认为 将其作为 QualifiedIdentifier
加上可选的 .*
有点让人头疼。
类似的论点可用于 Primary
。
此外,在 Import
或 Primary
中使用 QualifiedIdentifier
可能 会使解析器更加复杂。 (我很高兴听到真正的语言设计者对这个问题的看法。)换句话说,由于第 18 章的语法更适合实现,我不得不认为这个选择是经过深思熟虑的,并且使实现更容易。
底线
当然,上面给出的 QualifiedIdentifier
的建议用法在严格机械意义上描述了相同的语言。但是更喜欢书面语法有语义上的原因,也可能有实现上的原因。