Java是否有需要更多标识符信息的不明确语法?
注意:这个问题不是关于“Java没有指针” 在C语言中,代码Java是否有需要更多标识符信息的不明确语法?,java,parsing,semantics,symbol-table,Java,Parsing,Semantics,Symbol Table,注意:这个问题不是关于“Java没有指针” 在C语言中,代码identifier1*identifier2具有两种可能的含义: 如果identifier1是一个类型,那么这可能是一个指针声明 如果identifier1是一个变量,那么这可能是一个乘法语句 问题是,在构建语法树时,我无法选择正确的产品。我检查了Clang的代码,似乎Clang必须将类型检查(通过使用符号表)放到解析阶段(如果我错了,请纠正我) 然后我检查了javac(OpenJDK)的代码,似乎在解析阶段,没有涉及语义分析。解析器
identifier1*identifier2
具有两种可能的含义:
或者更一般地说,Java的语法是否不明确,以至于解析器在没有令牌流以外的其他信息的情况下无法选择产品?我认为Java没有这个问题,因为Java是强类型的。 而且,Java不支持指针,因此不可能出现上述问题。
我希望这能回答你的问题。我认为Java没有这个问题,因为Java是强类型的。 而且,Java不支持指针,因此不可能出现上述问题。
我希望这能回答您的问题。对于语言而言,标记化始终是上下文敏感的。但是,Java没有这样敏感的运算符。但是,您可以以这样的方式链接标记,使其产生歧义,但不仅仅是作为更大语法语句的一部分:
A
可以是公共类A{…}
或的一部分,如果(A
。
第一个是泛型类定义,第二个是比较
这只是我的第一个例子,但我想还有更多。
然而,操作符的定义通常非常狭窄,并且不能重载(就像在C/C++语言中一样)。此外,除了C/C++之外,只有一个访问器操作符(点:
),只有一个例外(自Java8以来,双冒号:
)。
在C++中有一堆,所以它就不那么混乱了。
关于Java是否总是语法上可判定的特定问题:
对一个实现良好的编译器总是可以根据令牌流来决定存在什么令牌。对于语言来说,令牌化始终是上下文敏感的。但是,Java没有这样敏感的运算符。但是,您可以以这样的方式链接标记,使其产生歧义,但不仅仅是作为更大语法语句的一部分:
A
可以是公共类A{…}
或的一部分,如果(A
。
第一个是泛型类定义,第二个是比较
这只是我的第一个例子,但我想还有更多。
然而,操作符的定义通常非常狭窄,并且不能重载(就像在C/C++语言中一样)。此外,除了C/C++之外,只有一个访问器操作符(点:
),只有一个例外(自Java8以来,双冒号:
)。
在C++中有一堆,所以它就不那么混乱了。
关于Java是否总是语法上可判定的特定问题:
对一个实现良好的编译器总是可以根据令牌流决定存在什么令牌。您的问题不容易回答;这取决于您拥有的生产规则。你说:
there's two production:
<pointer> ::= * {<type-qualifier>}* {<pointer>}?
or
<multiplicative-expression> ::= <multiplicative-expression> * <cast-expression>
它可以是一个名为bar
的指针,用于键入foo
,或者foo
与bar
的乘法可以解析为令牌流:
identifier_or_type ASTERISK identifier_or_type SEMICOLON
其余部分由解析器“业务逻辑”决定。因此,在解析器级别根本没有歧义,规则背后的逻辑决定了这两种情况的不同。您的问题不容易回答;这取决于您拥有的生产规则。你说:
there's two production:
<pointer> ::= * {<type-qualifier>}* {<pointer>}?
or
<multiplicative-expression> ::= <multiplicative-expression> * <cast-expression>
它可以是一个名为bar
的指针,用于键入foo
,或者foo
与bar
的乘法可以解析为令牌流:
identifier_or_type ASTERISK identifier_or_type SEMICOLON
其余部分由解析器“业务逻辑”决定。因此,在解析器级别根本没有歧义,规则背后的逻辑决定了这两种情况的不同。像
foo.bar.bla.i
这样的表达式不能单独使用语法进行有意义的解析。foo
、bar
和bla
中的每一个都可以是包名称的一部分、静态变量(此变量不适用于foo
)或内部类的名称
例如:
public class Main {
public static void main(String[] args) {
System.out.println(foo.bar.bla.i);
}
}
当静态变量
bla
被注释掉或没有注释掉时,这将打印21
或42
。像foo.bar.bla.i
这样的表达式不能单独使用语法进行有意义的解析。foo
、bar
和bla
中的每一个都可以是包名称的一部分、静态变量(此变量不适用于foo
)或内部类的名称
例如:
public class Main {
public static void main(String[] args) {
System.out.println(foo.bar.bla.i);
}
}
当静态变量
bla
被注释掉或没有注释掉时,这将打印21
或42
。我不太理解这个问题:java没有指针,所以这里不会有歧义,因为*
总是乘法。我不认为so@SanderDeDycker我认为OP是泛泛而谈,而不仅仅是关于*
。换句话说,在解析源代码时,是否有任何符号会导致歧义,而这些符号只能通过了解上下文中使用的类型来解决。有些运算符重载,可能会很简短