[dir] Zum Verzeichnisinhalt     [exercise] Zur Musterlösung     [download] (SHIFT + Linke Maustaste)
@=~
~p maximum_input_line_length = infinity

~A~<Dangling Else~>

The else part of ~{if~} statements is optional. Nested ~{if~} statements
like the following are errorprone:
~O~<dangling.in~>~{~-
{   
  int i, z;
  i = read();
  if (i>=0)
  if (i<10) z = 5+i;
  else      z = 0;
  print (z);
}
~}

C defines that the else belongs to the inner ~{if (i<10)~}.
The programmer might have intended to associate it to the
outer ~{if (i>=0)~}.
Hence the style guide requires to avoid such situations, e.g.
by additional curly braces. Your analysis tool shall emit a warning
if such a dangling else occurs:

~O~<dangling.out~>~{~-
"dangling.in", line 5:3 WARNING: beware of dangling else!
~}

The following questions may help to focus your attention on the
significant aspects of this problem:

1. Which are the adjacent tree contexts that will cause the warning?

2. In which context is the warning issued, and what is its precondition?

~B~<Solution~>

A warning is issued if the ~{Stmt~} subtree of a one-sided 
~{if~} statement is a two-sided ~{if~} statement. 
In order to produce the warning in the
lower context we associate an attribute ~{WarnSingleIf~}
to ~{Stmt~}. It indicates whether this ~{Stmt~} occurs immediately
below a one-sided ~{if~} context. There it is set to 1.
In all other contexts where ~{Stmt~} occurs on the righthand side
it is set to 0.

Using a default SYMBOL computation for ~{Stmt~}
avoids to take care of any other ~{Stmt~} context.
It is overridden by the RULE computation in the one-sided ~{if~} context.

~$~<dangling else computations~>~{
ATTR WarnSingleIf: int;

SYMBOL Stmt COMPUTE INH.WarnSingleIf = 0; END;

RULE: Stmt ::= 'if' '(' Expr ')' Stmt COMPUTE
  Stmt[2].WarnSingleIf = 1;
END;

RULE: Stmt ::= 'if' '(' Expr ')' Stmt 'else' Stmt COMPUTE
  IF (Stmt[1].WarnSingleIf,
  message (WARNING, "beware of dangling else!", 0, COORDREF));
END;
~}

~B~<Further Questions~>

1. Did you get messages on missing computations? 
If so, explain why.

2. Reconsider your solution when you have learned about
SYMBOL computations. How can you use them to simplify
your solution?

~B~<Output files~>

~O~<dangling.lido~>~{
~<dangling else computations~>
~}