Проблема в том, что предлагаемая вами грамматика неоднозначна.(Я имею в виду первую грамматику. Предлагаемое второе решение - это другой язык.)
Языки, которые используют конструкцию «else if» для сокращения вложенности скобок «if… end», используютспециальный токен:
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
Без слияния "else if" эти выражения были бы намного более громоздкими:
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
Это контрастирует с такими языками, как C, Java и многими другими, которыене требуйте, чтобы операторы «если» были прекращены, и, таким образом, демонстрировали конфликт «свисающий еще», сдвиг-уменьшение, который всегда разрешался в пользу сдвига.В этих языках, так как предложение «else» просто присоединяется к ближайшему несогласованному предложению «if», нет необходимости предоставлять специальный токен «else-if».
Теперь вы пытаетесь объединить этидва подхода с использованием слитного «else-if» без слияния, и это просто приводит к той же висячей проблеме else, которую пытался исправить явный брекетинг.Рассмотрим, например:
if C1 then S1 else if C2 then S2 else if C3 then S3 else S4 end S5 end
Теперь, что из следующих двух это представляет?
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
(Со временем я мог бы найти более простой пример. Выше две интерпретацииразличаются обстоятельствами, в которых выполняется S5
.)
Самое простое решение - использовать какой-то перегруженный токен «else if», как в приведенных выше примерах различных языков.(Или придумай свое :-))