【问题标题】:Can separated identifiers in the Java 7 grammar be reduced to qualified identifiers?Java 7 语法中的分隔标识符可以简化为限定标识符吗?
【发布时间】:2016-02-11 12:18:02
【问题描述】:

Java 7 syntax specification 指定了一个 QualifiedIdentifier,它包括:

QualifiedIdentifier:
    Identifier { . Identifier }

不过,在语法的后面部分,这个结构再次出现,而不是限定标识符:

ImportDeclaration: 
    import [static] Identifier { . Identifier } [. *] ;
Primary:
    Identifier { . Identifier } [IdentifierSuffix]

为什么这些部分要这样明确列出?他们不能简单地简化为:

ImportDeclaration: 
    import [static] QualifiedIdentifier [. *] ;
Primary:
    QualifiedIdentifier [IdentifierSuffix]

【问题讨论】:

  • 好的,谢谢,已更正。

标签: java syntax java-7 grammar jls


【解决方案1】:

一个真正的语法

首先,请了解您引用的语法(JLS 7 第 18 章)实际上并不是“Java 7 语法规范”(例如 The One True Grammar)。它是描述 Java 7 语法的语法。还有其他的,包括同一 JLS 文档的前几章中的那个。 JLS 本身在section 2.3, The Syntactic Grammar 中澄清了这一点:

第 4、6-10、14 和 15 章给出了 Java 编程语言的句法文法。该文法具有由词法文法定义的记号作为其终结符号。它定义了一组产生式,从目标符号 CompilationUnit(第 7.3 节)开始,描述令牌序列如何形成语法正确的程序。

第 18 章还给出了 Java 编程语言的句法语法,它更适合于实现而不是阐述。两种句法语法都接受相同的语言。

并且Chapter 18的介绍解释了其中介绍的语法专门用于参考实现:

前面章节(第 2.3 节)中零星介绍的语法更适合说明,但它不适合作为解析器的基础。本章介绍的语法是参考实现的基础。

所以不存在单一规范的 Java 语法。只有语言语法本身,可以用多种语法来表示。

建议的替代方案是否可以接受?

OP 询问是否

ImportDeclaration: 
    import [static] QualifiedIdentifier [. *] ;
Primary:
    QualifiedIdentifier [IdentifierSuffix]

会好的。是的,当然,为什么不呢?描述的是同一种语言,所以应该没问题。

那么他们为什么要这样做呢?

回想一下,第 18 章语法的目的是作为参考实现的基础。如果你仔细观察,你会发现QualifiedIdentifier 在它完全描述它所代表的“类似标识符的结构”(我发明的术语)的地方被一致地使用,但不是在它只是一个更大的“标识符-像构造”。

查看ImportDeclaration,很明显可选的尾随.*是被导入事物的标识符的一部分。在像import java.util.*; 这样的导入中,java.util 部分虽然用点分隔,但并不是真正的合格标识符。表示正在导入的事物的类似标识符的构造是整个短语java.util.*。所以把它当成QualifiedIdentifier 加上可选的.* 有点让人摸不着头脑。

Primary 可以使用类似的参数。

此外,在ImportPrimary 中使用QualifiedIdentifier 可能会使解析器更加复杂。 (我很高兴听到真正的语言设计者在这方面的意见。)换句话说,由于第 18 章的语法被认为更适合实现,我不得不认为这个选择是经过深思熟虑的,并且使实现更容易。

底线

当然,上面给出的QualifiedIdentifier 的建议用法从严格的机械意义上描述了相同的语言。但是更喜欢所写的语法有语义上的原因,也可能有实现方面的原因。

【讨论】:

  • 啊谢谢!你是对的,他们不使用QualifiedIdentifier,因为它在语义上不正确,因为它实际上不是限定标识符,而是任何类型的较长标识符的一部分。
  • 关于让它变得更复杂的部分:我实际上正在开发 Java 解析器(我之前为脚本语言编写了一个解析器:capri.ghostkernel.org),我认为它不应该成功更复杂,因为在实际解决导入的内容时,您必须以两种方式遍历底层值。但是这里将其解析为限定标识符是更正确的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2016-04-28
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 2020-06-16
相关资源
最近更新 更多