Возможно ли параллельное реляционное выражение (т.е. 1 <2 <3) в JavaCC с использованием JJTree? - PullRequest
0 голосов
/ 07 августа 2011

Я просмотрел пример «Интерпретатора», поставляемого с пакетом JavaCC. Он допускает синтаксис параллельного реляционного выражения, но не дает правильного ответа.

boolean a;
a = 1<2<3;
write a;

Это даст ClassCastException, потому что интерпретатор обрабатывает "1 <2" и помещает логическое значение в стек, в то время как третья переменная, 3, является целым числом, поэтому она не сопоставима с логическим значением. </p>

Я пытаюсь изменить ASTLTNode.java, который содержит

public class ASTLTNode extends SimpleNode {
    public ASTLTNode(int id) {
        super(id);
    }

    public ASTLTNode(ShawaParser p, int id) {
        super(p, id);
    }

    public void interpret()
    {
       jjtGetChild(0).interpret();
       jjtGetChild(1).interpret();
       stack[--top] = new Boolean(((Integer)stack[top]).intValue() <
                           ((Integer)stack[top + 1]).intValue());
    }
}

Если я добавлю «top ++» в конце interpret (), стек сохранит последнее значение, но когда процесс завершится, он покажет последнюю цифру, а не логическое значение.

У вас, ребята, есть идеи сделать это? Большое спасибо.

1 Ответ

1 голос
/ 07 августа 2011

Вы правы, что синтаксис 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. Это может напомнить вам о реализации короткого замыкания и / или. Надеюсь, это поможет.

...