Java编译器和其他编译器如何处理以下场景;哪里有嵌套if没有大括号?
// In Java, to which of the 'if's does this 'else' belong?
// If bOne=false and bTwo=true, will the println run?
boolean bOne = false;
boolean bTwo = true;
if (bOne)
if (bTwo)
bTwo = bTwo; // do nothing
else
System.out.println("bOne:" + bOne + ". bTwo:" + bTwo);
答案 0 :(得分:6)
else
子句适用于第二个if语句。首先,它应该被理解为:
if (bOne)
if (bTwo)
bTwo = bTwo; // do nothing
else
System.out.println("bOne:" + bOne + ". bTwo:" + bTwo);
然后应该重写代码以使用花括号。
这适用于许多命令式编程语言,一个值得注意的例外是Python,它具有显着的缩进而不是花括号。
答案 1 :(得分:3)
这称为dangling else问题。解决此问题的规则是else
属于最接近的if
。因此,在该示例中,else
属于if (bTwo)
。
答案 2 :(得分:1)
正如其他人已经说过的那样,它确实属于"最近的if
"。但是,为了避免这个问题,总是使用大括号(和适当的缩进),这样就不需要通过理解编译器的工作原理来解决这个问题。
顺便说一句,编译器以这种方式解决了这个问题(伪代码):
process_if()
{
expect_token("if");
next_token();
expect_token("(");
next_token();
condition = parse_expression();
expect_token(")");
next_token();
then_part = parse_statement_or_block();
if (current_token == "else")
else_part = parse_statement_or_block();
else
else_part = nothing;
}
parse_statement_or_block()
{
if (current_token() == "{")
do
{
statements += parse_statement();
} while(current_token() != "}");
else
statements = parse_statement();
}
parse_statement()
{
switch(current_token())
{
case "while":
process_while();
break;
case "for":
process_for();
break;
case "if":
process_if();
break;
....
}
}
这个解析器的工作方式是它读取第一个if,而statement
里面是另一个if
,所以它转到process_if
,取condition
,then_part
,然后检查else
,并将其作为else_part
的{{1}}。然后回到第一个if语句并找到" no else there" (因为它已被消耗)。
实际完成此编译器的实际编译器代码:
https://github.com/Leporacanthicus/lacsap/blob/master/parser.cpp#L1854