Java-программа, которая действует как ассемблер (для вымышленного языка): не завершится во время цикла - PullRequest
0 голосов
/ 08 марта 2011

По сути, это двухпроходный ассемблер, и я работаю над реализацией точек входа в данный файл сборки.Формат команды следующий:

Prog     .ORIG
         .ENT    some,entry,point
some     LD      R0,entry
entry    LD      R1,point
point    .FILL   #42
         .END    some

Соответствующей частью является строка .ENT.Это строка, на которой ассемблер зацикливается.

Первый проход заботится о обработке .ENTs, но он не будет работать ни с чем, кроме двух аргументов (то есть более одной запятой).Это работает для двух операндов и меньше, хотя.Код для конкретной части .ENT выглядит следующим образом:

String comma = ",";
String entry = "";
String[] tempEntryArray = new String[2];
int indexOfComma = read.indexOf(comma);
int startingIndex = 17;
int numOperands = 1;
while (indexOfComma != -1) {
    if ((indexOfComma-startingIndex) == 0) {
        return "An operand must precede the comma.";
    }
    if (numOperands > 4) {
        return "The .ENT psuedo-op on line " + lineCounter
               + " has more than 4 operands.";
    }
    entry = overSubstring(read, startingIndex, indexOfComma);
    if (entry.contains(" ")) {
        return "The operand \"" + entry + "\" on line " 
               + lineCounter + " has a space in it.";
    }
    if (entry.length() > 6) {
        return "The operand \"" + entry + "\" on line "
               + lineCounter + " is longer than 6 characters.";
    }
    machineTables.externalSymbolTable.put(entry, tempEntryArray);
    entry = read.substring(indexOfComma + 1);
    startingIndex = indexOfComma + 1;
    indexOfComma = entry.indexOf(comma);
    if (indexOfComma != -1) {
        indexOfComma += (startingIndex - 1);
    }
    numOperands++;
}
entry = overSubstring(read, startingIndex, read.length());
if (entry.contains(" ")) {
    return "The operand \"" + entry + "\" on line " 
           + lineCounter + " has a space in it.";
}
if (entry.length() > 6) {
    return "The operand \"" + entry + "\" on line "
           + lineCounter + " is longer than 6 characters.";
}
machineTables.externalSymbolTable.put(entry, tempEntryArray);

read - строка, содержащая одну строку входного файла.overSubstring - это метод, который будет работать аналогично подстроке, но он будет возвращать символ пробела, если он читает пустую строку.

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

Я был бы очень признателен, если бы кто-то мог помочь мне с этой проблемой.

Спасибо.

1 Ответ

1 голос
/ 08 марта 2011

Я думаю, что вы читаете одно и то же значение indexOfComma бесконечно. Вместо всего этого startingIndex и substring() бизнеса просто используйте String#indexOf(String, int) вместо String#indexOf(String), чтобы правильно пропустить предыдущие индексы, которые вы уже нашли.

Получите indexOfComma последовательно. Примерно так:

int indexOfComma = -1;
int numOperands = 1;
while ((indexOfComma = read.indexOf(comma, indexOfComma+1)) != -1) {
    // snip...
    machineTables.externalSymbolTable.put(entry, tempEntryArray);
    numOperands++;
}
...