The dangling else is a problem in computer programming in which an optional else clause in an if–then(–else) statement results in nested conditionals being ambiguous. Formally, the reference context-free grammar of the language is ambiguous, meaning there is more than one correct parse tree.
Contents
- Avoiding ambiguity while keeping the syntax
- Avoiding ambiguity by changing the syntax
- Examples
- C
- Avoiding the conflict in LR parsers
- References
In many programming languages one may write conditionally executed code in two forms: the if-then form, and the if-then-else form – the else clause is optional:
if a then sif b then s1 else s2This gives rise to an ambiguity in interpretation when there are nested statements, specifically whenever an if-then form appears as s1
in an if-then-else form:
In this example, s
is unambiguously executed when a
is true and b
is true, but one may interpret s2
as being executed when a
is false (thus attaching the else to the first if) or when a
is true and b
is false (thus attaching the else to the second if). In other words, one may see the previous statement as either of the following expressions:
The dangling else problem dates to ALGOL 60, and has been resolved in various ways in subsequent languages. In LR parsers, the dangling else is the archetypal example of a shift-reduce conflict.
Avoiding ambiguity while keeping the syntax
This is a problem that often comes up in compiler construction, especially scannerless parsing. The convention when dealing with the dangling else is to attach the else to the nearby if statement, allowing for unambiguous context-free grammars, in particular. Programming languages like Pascal and C follow this convention, so there is no ambiguity in the semantics of the language, though the use of a parser generator may lead to ambiguous grammars. In these cases alternative grouping is accomplished by explicit blocks, such as begin...end
in Pascal and {...}
in C.
Depending on the compiler construction approach, one may take different corrective actions to avoid ambiguity:
Avoiding ambiguity by changing the syntax
The problem can also be solved by making explicit the link between an else and its if, within the syntax. This usually helps avoid human errors.
Possible solutions are:
if e do s
for the one-alternative case and if e1 then e2 else e3
for the general case.Examples
Concrete examples follow.
C
In C, the grammar reads, in part:
statement = ... | selection-statement selection-statement = ... | IF ( expression ) statement | IF ( expression ) statement ELSE statementThus, without further rules, the statement
could ambiguously be parsed as if it were either:
or:
In practice in C the first tree is chosen, by associating the else
with the nearest if
.
Avoiding the conflict in LR parsers
The above example could be rewritten in the following way to remove the ambiguity:
statement = ... | selection-statement statement-with-else = ... | selection-statement-with-else selection-statement = ... | IF ( expression ) statement | IF ( expression ) statement-with-else ELSE statement selection-statement-with-else = ... | IF ( expression ) statement-with-else ELSE statement-with-elseAny other statement-related grammar rules may also have to be duplicated in this way if they may directly or indirectly end with a statement
or selection-statement
non-terminal.