Как разные языки справляются с «висящим другим»? - PullRequest
7 голосов
/ 09 июня 2009

Я часто вижу висящее остальное как:

if (x > 0)
  if (y > 0)
    print "hello"
else
  print "world"

синтаксический анализатор или интерпретатор фактически сопоставят else с ближайшим оператором if, который является "if (y> 0)".

Есть ли в каком-либо языке ловушка, позволяющая на самом деле сопоставить else с внешним if или с последним if? (кроме очевидного Питона)

Ответы [ 9 ]

6 голосов
/ 09 июня 2009

За исключением использования чувствительных к пространству языков (таких как Python, как вы сказали), я не понимаю, почему какая-либо разумная интерпретация соответствовала бы самому внешнему блоку if.

Некоторые языки запрещают эту потенциальную двусмысленность:

  1. Требующие фигурные скобки для всех блоков и
  2. Предоставление специального синтаксиса "else if", обычно elsif, elif или elseif.
3 голосов
/ 09 июня 2009

Если бы какой-либо язык делал это (кроме языков, ориентированных на отступы), они должны были бы войти в один из списков "какой язык худший".

Именно поэтому я почти всегда использую фигурные скобки для условных выражений и 100% времени, когда есть вложенные условные выражения или циклы. Несколько лишних символов стоит исключить возможность путаницы.

2 голосов
/ 09 июня 2009

В Perl скобки не являются обязательными, что помогает нам избежать таких проблем:

if ($x > 0) {
    if ($y > 0) {
        print "hello"
    }
    else {
        print "world"
    }
}

против

if ($x > 0) {
    if ($y > 0) {
        print "hello"
    }
}
else {
    print "world"
}

IIRC, большинство руководств по стилю С требуют / рекомендуют скобки для циклов и условных выражений.

1 голос
/ 09 июня 2009

Принцип работы C # заключается в том, что он соответствует операторам else в порядке используемых операторов else.

т.

if (x == 1)
    if (y == 1)
        Console.WriteLine("Hello");
    else
        Console.WriteLine("World");
else
    Console.WriteLine("All your base are belong to us.");

однако, если вы хотите изменить, куда идет другое.

if (x == 1)
{
    if (y == 1)
        Console.WriteLine("Hello World");
}
else
    Console.WriteLine("All your base are belong to us.");
1 голос
/ 09 июня 2009

В Python вы не можете быть неоднозначным по этому поводу. Либо у вас есть

 if (x > 0):
   if (y > 0):
     print "hello"
 else:
   print "world"

или

 if (x > 0)
   if (y > 0)
     print "hello"
   else:
     print "world"

Отступ показывает, какое «если» соответствует «другому». [Примечание: как ни старайся, я не могу заставить «else» в первом примере правильно выстроиться под первым «if».]

На всех языках, которые я видел, которые допускают эту конкретную двусмысленность, "else" совпадает с самым последним "if". Это может быть не верно для всех языков, которые когда-либо существовали. Обычно при написании синтаксического анализатора проще всего сопоставить «else» с ближайшим «if» в стеке.

Аналогичный вопрос: каков результат 5 - 2 + 1? Это 4 или 2? Лично я всегда использую скобки, когда пишу (x - y) + z или x - (y + z), потому что я никогда не могу вспомнить, каким образом пойдет парсер.

1 голос
/ 09 июня 2009

C # делает "правильную" вещь. Интеллектуальный отступ Visual Studio также автоматически помещает его в нужное место:

if (x > 0)
    if (y > 0)
        Console.WriteLine("hello");
    else
        Console.WriteLine("world");

Надеюсь, это должен быть только теоретический вопрос, поскольку привычка добавлять кудрявые слова везде должна быть глубоко укоренена в большинстве производных C, в противном случае вы открываете возможность неприятных сюрпризов.

0 голосов
/ 31 марта 2017

COBOL, до введения END-IF, определяет, что ELSE принадлежит ближайшему IF.

В противном случае, кроме предыдущего, необходимо сбалансировать IF с тем же количеством ELSE. Поскольку должен быть императив, необходимо добавить предложение NEXT SENTENCE. Как и в любом другом случае [1] в COBOL, выбор решения представляется наиболее многословным.

[1]: ОЦЕНИТЬ ПРИ ИНОСТРАННОМ ОБЛУЧЕНИИ

0 голосов
/ 09 июня 2009

Большинство языков будут соответствовать else с самым внутренним if, и это действительно единственная разумная вещь для компилятора без учета пробелов. Многие IDE, как упоминает Джефф, форматируют код в соответствии со структурой, но на самом деле использование скобок вокруг всех блоков кода - это разумный способ справиться с этим.

0 голосов
/ 09 июня 2009

Если он не совпадает с самым последним if, либо все становится бессмысленным, либо вы не можете сопоставить другие if. Это (единственная реальная альтернатива, которую я могу представить) не имеет смысла:

if(first)
    if(second)
        if(third)
            doFirst();
        else
            doSecond();
        else
            doThird();

что слишком много.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...