Java JLS语法如何匹配简单字段访问(obj.f)?
我一直在研究如何解析简单的字段访问:Java JLS语法如何匹配简单字段访问(obj.f)?,java,java-8,language-lawyer,grammar,jls,Java,Java 8,Language Lawyer,Grammar,Jls,我一直在研究如何解析简单的字段访问: obj.field 在我看来,FieldAccess产品的第一个变体可能涉及到了这一点 现场访问: 主标识符 super标识符 TypeName超级标识符 然后,该Primary应该参与解析obj部分。Primary似乎不参与解析像ExpressionName这样的简单引用。这似乎是通过PostfixExpression实现的 后固定表达: 初级 表达式名称 增加后的表达 递减后压力 而且,AFAICT,PostfixExpression不是与Prima
obj.field
在我看来,FieldAccess产品的第一个变体可能涉及到了这一点
现场访问:-
主
标识符super
标识符TypeName
超级
标识符
然后,该Primary应该参与解析obj
部分。Primary似乎不参与解析像ExpressionName这样的简单引用。这似乎是通过PostfixExpression实现的
后固定表达:-
初级
表达式名称
增加后的表达
递减后压力
编辑:
我对语法中非终结符之间的关系做了一个分析。如果边为蓝色,则非终端在非终端的开始处,即箭头所指的位置处,有一个左递归使用。正如您已经指出的,
obj
不是主要的,因此,生产主要的
标识符不适用于obj.字段
。由于不涉及super
键,其他选项也不适用,因此整个FieldAccess不适用
这没什么好担心的,因为这只是一个命名的语法规则,不是让Java源代码访问字段的必要条件
正如您还注意到的,PostfixExpression包括Primary,但不仅如此,它还包括ExpressionName:
因此,obj.field
匹配ExpressionName,因此匹配PostfixExpression。现在,从表达式到PostfixExpression有一个长长的生产链,包含了整个运算符优先级规则,但简单地说,PostfixExpression在任何地方都是允许的,其中表达式是允许的
有一个明显的分歧,作业:
赋值是表达式,因此它们也可能出现在赋值的右侧,但左侧是特殊的。在这里,我们可以看到FieldAccess,它不属于obj.field
(非直观)以及ExpressionName,它与obj.field
匹配
也许有助于记住,当解析
obj.field
时,解析器不知道它是字段访问。也可能是这样的情况,obj
是一个包,field
是一个类名,obj
是一个类名,field
是一个内部类名。需要将其解析为字段的是周围的上下文(它仍然可以是类obj
中的静态
字段)
FieldAccess产品列出了那些在解析时可以识别的明确的字段访问的情况,而无需查看其周围的上下文。您在寻找吗?@Tunaki,没有。这是从第19章链接而来的。好吧,这就是主字段。第19章也有相关链接。@Tunaki,如果你说的是“Java编程语言语法的这一部分是不寻常的,在两个方面……”部分,那么这是相关的。但这并不能真正解决问题。“名称稍后与主表达式组合在一起”似乎不能解决问题,因为没有括号,无法从主表达式访问PostfixExpression。Ok。“
obj.field
匹配ExpressionName”是有道理的,所以我的错误假设是涉及到Primary。这就是我错过的。对我来说,foo.bar.baz代码>是一个明确的字段访问,即使foo.bar
不明确。否,foo.bar.baz
要么不明确,要么根本不是有效的构造,因为它不是语句。但是,如果前面有import
,则它是有效的构造import foo.bar.baz代码>,但不是字段访问。当前面加上例如x=
:x=foo.bar.baz时,它将是一个字段访问代码>。无歧义字段访问的示例有this.field
或foo().bar
…很抱歉造成混淆。我的示例被破坏了,因为字段访问不允许作为顶级表达式语句。我的意思是,在(foo.bar.baz)
中,当解析从表达式开始时,baz
在字段名称中是明确的,但是foo.bar
是指类(整个编译为getstatic指令)还是本身是表达式(整个编译为getfield指令)是不明确的。问题是,在解析过程中遇到foo.bar.baz
时,此时您不知道它的含义,即,即使我们处于表达式上下文中,我们也必须知道foo.bar.baz
后面的内容,例如后续的。另一个名称
可能会使它变得模棱两可,但如果后面跟着.class
,这显然不是现场访问。后续的+
或=
将是另一种情况。我将“不明确”解释为“语法中有多条路径最终弹出开始生产并消耗整个输入。”如果“不明确”的意思是“提交变体所需的前瞻量是无限的”那么我想我们基本上同意了。
ExpressionName:
Identifier
AmbiguousName . Identifier
AmbiguousName:
Identifier
AmbiguousName . Identifier
Assignment:
LeftHandSide AssignmentOperator Expression
LeftHandSide:
ExpressionName
FieldAccess
ArrayAccess