这些'如果是''其他'属于哪个?为什么?

时间:2014-10-23 20:45:20

标签: java

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);

3 个答案:

答案 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,取conditionthen_part,然后检查else,并将其作为else_part的{​​{1}}。然后回到第一个if语句并找到" no else there" (因为它已被消耗)。

实际完成此编译器的实际编译器代码:

https://github.com/Leporacanthicus/lacsap/blob/master/parser.cpp#L1854