Глядя на эти произведения:
If: [
[ 'IfBlock' ],
[ 'IfBlock ELSE Body IF_END ']
]
Мне кажется, что грамматика говорит, что оператор if
должен заканчиваться IF_END
, только если включает else
пункт. if
, в котором отсутствует предложение else
, не может быть прервано IF_END
.
Это не мое понимание синтаксиса визуальных основ c. END_IF
является обязательным в многострочном синтаксисе и не используется в однострочном синтаксисе.
Таким образом, у вас есть два конфликта, потому что ваша If
продукция принимает некоторые операторы с END_IF
и некоторые без:
Для if
операторов без END_IF
имеется двусмысленность classi c "dangling else".
Кроме того, для многострочного В операторах if
без END_IF
грамматика не позволяет определить, является ли следующий оператор частью последнего предложения в операторе if
или новым оператором. (Вот почему многострочным if
операторам необходимо END_IF
.
Неоднозначность «висячее другое» относительно мягкая, то есть нормальное разрешение, которое предпочитает сдвиг для уменьшения, приведет к правильный результат. Если вы хотите устранить сообщение об ошибке, вы можете сделать разрешение явным, используя правила приоритета, давая ELSE
и ELSE_IF
более высокий приоритет, чем IF
. Чтобы использовать эту технику, вы должны сделать IF
видимым в правилах, которые зависят от приоритета, что в основном означает удаление IF
из IfBLock
, чтобы оставить вас с:
IfBlock: [
[ 'Expression THEN Body' ],
[ 'IfBlock ELSE_IF Expression THEN Body' ]
],
If: [
[ 'IF IfBlock' ],
[ 'IF IfBlock ELSE Body' ] // IF_END removed
]
Вам также понадобятся отношения приоритета:
[ 'left', 'IF' ],
[ 'left', 'ELSE', 'ELSE_IF' ]
Это более или менее заставит вас переходить на однострочные операторы if, за исключением того, что вам нужно заменить Block
чем-то, что не позволяет TERMINATOR
.
для многострочных if
операторов. однако вам потребуется другой синтаксис:
END_IF
является обязательным
Должен быть TERMINATOR
после THEN
и ELSE
, а б прежде ELSE
и END_IF
. Другими словами, блоки операторов в многострочном if
должны начинаться с начала строки и заканчиваться TERMINATOR
.
Эти ограничения не являются только косметическими c: они есть, потому что в противном случае невозможно поместить оператор после многострочного if
, поскольку без END_IF
любое последующее утверждение будет добавлено к последнему предложению THEN
или ELSE
.