Вы правы, что синтаксис SPL (Stupid Programming Language) допускает выражения типа 1 < 2 < 3
- вы можете увидеть это в спецификации:
void RelationalExpression() #void :
{}
{
AdditiveExpression()
(
"<" AdditiveExpression() #LTNode(2)
|
">" AdditiveExpression() #GTNode(2)
|
"<=" AdditiveExpression() #LENode(2)
|
">=" AdditiveExpression() #GENode(2)
)*
}
Однако, только потому, что выражение 1 < 2 < 3
является синтаксически разрешено, не означает, что оно семантически разрешено.
Как вы обнаружили, ваше выражение проходит проверку синтаксиса, но имеет то, что называется статическая семантическая ошибка , в частности ошибка типа.
Существует много видов этих семантических ошибок в популярных языках программирования. Например, в Java вы можете объявить метод, принимающий четыре параметра, но если вы вызовете его с двумя параметрами, что произойдет? Ваш вызов синтаксически правильный (идентификатор, за которым следует левая часть, за которой следует список выражений через запятую), но есть семантическая ошибка: количество аргументов в вызове не соответствует количеству объявленных параметры.
Если вы хотите, чтобы 1 < 2 < 3
было допустимым логическим выражением, которое возвращает истину, если 1<2
и 2<3
(например, Python), тогда вам нужно изменить семантику SPL. Так как это ориентировано на стек, что вы можете сделать? Посмотрим. Предположим, у вас было
x < y < z
Сначала вы нажимаете x, нажимаете y и делаете меньше, чем. Теперь, если x < y
, вы захотите заменить вершину стека (в настоящее время true
) на y
, а затем продолжить тест (а именно y < z
). Но если вы обнаружили, что x < y
выдает false, то вам нужно оставить false на вершине стека и пропустить оставшиеся меньше .
Это работает, даже если у вас есть
e1 < e2 < e3 < e4 < e5 < e6
и так далее. Хитрость заключается в том, чтобы выручить рано, когда вы обнаружите, что <
возвращает false. Это может напомнить вам о реализации короткого замыкания и / или. Надеюсь, это поможет.