The designers carried forth the "dangling else" problem from C. Modula is based on Pascal which is based on Algol. However, Wirth eliminated the "dangling else" problem when he designed the grammar for Modula. For those who are staring at the monitor, the "dangling else" problem is a grammatical ambiguity that is introduced by the grammatical productions "if-statement" and "if-else-statement." The dangling else problem is the reason why we have to write code such as:
if (expression)
{
if (some_other_expression)
some_statement;
}
else
some_statement;
Contrary to popular belief, the curly braces in Java, C++, and C are not part of the of the control structures. Curly braces belong to a grammatical production known as "compound-statement" (a.k.a. "block"). The grammatical productions for "if-statement" and "if-else-statement" are:
if-statement ::= "if" "(" expression ")" statement
if-else-statement ::= "if" "(" expression ")" statement "else" statement
statement ::= if-statement | if-else-statement | for-statement | compound-statement | assignment-statement ...
coupound-statement ::= "{" statement-list "}"
statement-list ::= statement | statement-list statement
Now, let's examine the "dangling else" problem in action.
if (expression1)
if (some_other_expression)
some_statement;
else
some_statement;
To which "if" does the "else" belong? Using the above grammatical productions, the code can be parsed as an outer "if-else-statement" with an inner "if-statement" or an outer "if-statement" with an inner "if-else-statement" Since "if-statement" and "if-else-statement" are both statements, the parser has no way to determine which “if” should be matched with the “else.” The practice of matching the innermost “if” with the “else” is a deus ex machina technique that is forced into the grammar by the compiler writer.
Let’s examine the first example in detail.
if (expression)
{
if (some_other_expression)
some_statement;
}
else
some_statement;
The above code snippet works as expected because it gets parsed as an outer “if-else-statement” with an inner “compound-statement.” The production for "compound-statement" is resolved before the parser encounters the "else" token; therefore, the innermost "if" that is seen by the parser is the outer "if."