The problem is that the grammar you propose is ambiguous. (The first grammar, I mean. The proposed second solution is a different language.)
Languages which use an "else if" construct in order to cut down on the nesting of "if … end" brackets use a special token:
Ruby Python VB Shell
---------------- ------------------- ----------------- --------------------
if n > 0 if n > 0: If n > 0 Then if ((n>0)); then
puts "Greater" print ("Greater") Print "Greater" echo Greater
elsif n == 0 elif n == 0: ElseIf n = 0 Then elif ((n==0)); then
puts "Equal" print ("Equal") Print "Equal" echo Equal
else else: Else else
puts "Less" print ("Less") Print "Less" echo Less
end End fi
Without the fused "else if", these expressions would be much more cumbersome:
Ruby Python VB Shell
---------------- ------------------- ----------------- --------------------
if n > 0 if n > 0: If n > 0 Then if ((n>0)); then
puts "Greater" print ("Greater") Print "Greater" echo Greater
else else: Else else
if n == 0 if n == 0: If n = 0 Then if ((n==0)); then
puts "Equal" print ("Equal") Print "Equal" echo Equal
else else: Else else
puts "Less" print ("Less") Print "Less" echo Less
end end End fi
end End fi
This constrasts with languages like C, Java, and many others which do not require that "if" statements be terminated, and thus exhibit the "dangling else" shift-reduce conflict, which is always resolved in favour of the shift. In those languages, since the "else" clause simply attaches to the closest unmatched "if" clause, there is no need to provide a special "else-if" token.
Now, you are attempting to combine these two approaches by using a fused "else-if" without fusing it, and that simply leads to the same dangling else problem which the explicit bracketing was attempting to fix. Consider, for example:
if C1 then S1 else if C2 then S2 else if C3 then S3 else S4 end S5 end
Now, which of the following two does this represent?
if C1 then if C1 then
S1 S1
else if C2 then else
S2 if C2 then
else S2
if C3 then else if C3 then
S3 S3
else else
S4 S4
end end
S5 S5
end end
(With more time I might have found a simpler example. The above two interpretations differ in the circumstances in which S5
is executed.)
The simplest solution is to use some fused "else if" token, as in the various language examples above. (Or think up your own :-) )