Dangling elseThe dangling else is a problem in programming of parser generators in which an optional else clause in an if–then(–else) statement can make nested conditional statements ambiguous. Formally, the reference context-free grammar of the language is ambiguous, meaning there is more than one correct parse tree. DescriptionIn many programming languages, one may write conditionally executed code in two forms: the if-then form, or the if-then-else form. (The else clause is optional.): if a then s if b then s1 else s2 Ambiguous interpretation becomes possible when there are nested statements; specifically when an if-then-else form replaces the statement if a then if b then s1 else s2 In this example, if a then { if b then s1 } else s2 if a then { if b then s1 else s2 } The dangling-else problem dates back to ALGOL 60,[1] and subsequent languages have resolved it in various ways. In LR parsers, the dangling else is the archetypal example of a shift-reduce conflict. ExamplesConcrete examples follow. CIn C, the grammar reads, in part: statement = ... | selection-statement selection-statement = ... | IF ( expression ) statement | IF ( expression ) statement ELSE statement Thus, without further rules, the statement if (a) if (b) s; else s2;
could ambiguously be parsed as if it were either: if (a)
{
if (b)
s;
else
s2;
}
or: if (a)
{
if (b)
s;
}
else
s2;
The C standard clarifies that an Approaches to avoid the issueAvoiding ambiguity while keeping the syntaxThis problem 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,[3] allowing for unambiguous context-free grammars, in particular. Programming languages like Pascal,[4] C,[2] and Java[5] 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 Depending on the compiler construction approach, one may take different corrective actions to avoid ambiguity:
Avoiding ambiguity by changing the syntaxThe 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.[7] Possible solutions are:
Avoiding the conflict in LR parsersThe above example could be rewritten in the following way to remove the ambiguity : statement: open_statement | closed_statement ; open_statement: IF '(' expression ')' statement | IF '(' expression ')' closed_statement ELSE open_statement ; closed_statement: non_if_statement | IF '(' expression ')' closed_statement ELSE closed_statement ; non_if_statement: ... ; Any other statement-related grammar rules may also have to be duplicated in this way if they may directly or indirectly end with a However, we give grammar that includes both of if and while statements. statement: open_statement | closed_statement ; open_statement: IF '(' expression ')' statement | IF '(' expression ')' closed_statement ELSE open_statement | WHILE '(' expression ')' open_statement ; closed_statement: simple_statement | IF '(' expression ')' closed_statement ELSE closed_statement | WHILE '(' expression ')' closed_statement ; simple_statement: ... ; Finally, we give the grammar that forbids ambiguous IF statements. statement: open_statement | closed_statement ; open_statement: IF '(' expression ')' statement | IF '(' expression ')' closed_statement ELSE open_statement | WHILE '(' expression ')' open_statement ; closed_statement: simple_statement | IF '(' expression ')' closed_statement ELSE closed_statement | WHILE '(' expression ')' closed_statement ; simple_statement: ... ; With this grammar the statement statement open_statement IF '(' expression ')' closed_statement ELSE open_statement 'if' '(' 'a' ')' closed_statement 'else' 'd' and then the parsing fails trying to match statement open_statement IF '(' expression ')' statement IF '(' expression ')' closed_statement IF '(' a ')' (IF '(' expression ')' closed_statement ELSE closed_statement) IF '(' a ')' (IF '(' b ')' c ELSE 'd') See alsoReferences
|
Portal di Ensiklopedia Dunia