Проблемы с получением утверждения "если", JAVA - PullRequest
0 голосов
/ 17 марта 2011

У меня есть программа, которая проходит и читает «токены», которые могут быть либо строкой (символом), либо числом. Он использует postfix и стек для оценки простых команд.

Например:

/x 100 def
/y 200 def
x y add

должно вернуть 300. В первой строке определяется переменная с именем "x" и устанавливается значение 100. Для этого читатель добавляет "/ x" и "100" в стек и останавливается, когда достигает значения "def". оператор, который говорит ему, нужно создать токен с символом, называемым «x», и его значением будет 100. Тогда стек пуст, и в следующий раз, когда «x» будет выдвинут, интерпретатор должен автоматически заменить его своим значением. Вот где моя проблема.

Это мой переводчик:

while ( r.hasMoreTokens() ) {
            Token t = r.nextToken();

            if ( !t.isSymbol() ) {
                operands.push( t );
            } else if (env.contains(t.getSymbol())) {
                Token tmp = env.get(t.getSymbol());
                operands.push(tmp); 
            } else if (t.getSymbol().startsWith("/")) {
                operands.push(t);
            } else if ( t.getSymbol().equals( "def" ) ){
                execute_def();
            } else if ( t.getSymbol().equals( "add" ) ) {
                execute_add();
            } else if ( t.getSymbol().equals( "sub" ) ) {
                execute_sub();
            } else if ( t.getSymbol().equals( "mul" ) ) {
                execute_mul();
            } else if ( t.getSymbol().equals( "exch" ) ) {
                execute_exch();
            } else if ( t.getSymbol().equals( "dup" ) ) {
                execute_dup();
            } else if ( t.getSymbol().equals( "pop" ) ) {
                execute_pop();
            } else if ( t.getSymbol().equals( "pstack" ) ) {
                execute_pstack();
            } else if ( t.getSymbol().equals( "moveto" ) ) {
                execute_moveto();
            } else if ( t.getSymbol().equals( "lineto" ) ) {
                execute_lineto( g );
            } else if ( t.getSymbol().equals( "arc" ) ) {
                execute_arc( g );
            } else if ( t.getSymbol().equals( "quit" ) ) {
                execute_quit();
            } else {
                System.out.println( "ILLEGAL SYMBOL: " + t );
            }
        }

Как только переменные определены правильно, я не могу войти в этот первый else if и изменить значение. Поскольку я не могу этого сделать, я никогда ничего не помещаю в стек и в итоге получаю ошибку пустого стека. Вот методы contains() и get() из env (среда):

public boolean contains(String key) {
        Elem tmp = top;
        for (int i = 0; i < size; i++) {
            if (tmp.key == key) {
                return true;
            } else {
                tmp = tmp.next;
            }
        }
        return false;
    }

public Token get(String key) {
        Elem tmp = top;
        int counter = 0;
        boolean found = false;
        for (int i = 0; i < size; i++) {
            if (tmp.key == key) {
                found = true;
                break;
            } else {
                tmp = tmp.next;
            }
            counter++;
        }

        if (found == true) {
            tmp = top;
            for (int i = 0; i <= counter; i++) {
                tmp = tmp.next;
            }
            return tmp.value;
        } else {
            throw new BadKeyQueryException();
        }
    }

Я использую связанные элементы в среде, чтобы отслеживать символы. Элем - это вложенный класс в Environment:

private static class Elem {
        private String key;
        private Token value;
        private Elem next;

        private Elem(String key, Token value, Elem next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }

Спасибо за любую помощь, ребята!

Ответы [ 2 ]

0 голосов
/ 17 марта 2011

Строки в Java являются объектами, а не примитивами.

Когда вы говорите:

int i = 5;

я храню значение "5".

Когда вы говорите:

String s = "string";

s хранит значение ссылки на «строку».

Сравнение s со строкой вернуло бы false, даже если они содержат то же значение, когда вы там печатаете. Это связано с тем, что компьютер сравнивает ссылку на память, содержащую «строку», с другой ссылкой на память, содержащую «строку». Те же значения, но разные ссылки.

Кроме того, вы устанавливаете «t» для нескольких различных значений в вашем коде. Попробуйте установить t один раз, перед всем, и предварительно вычисленное значение t для вашего блока if-else-if.

0 голосов
/ 17 марта 2011

Вы можете вызвать getSymbol () только один раз, поэтому вам просто нужно сохранить значение из него.Вот начало ваших утверждений, вы должны быть в состоянии изменить другие так же, как

if ( !t.isSymbol() ) {
    operands.push( t );
    continue;
}

String symbol = t.getSymbol();

if (env.contains(symbol)) {
    Token tmp = env.get(symbol);
    operands.push(tmp); 
} else if (symbol.startsWith("/")) {
    operands.push(t);
...
...