2013-02-23 1 views
0

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

Traceback <most recent call last>: 
    File "Assembler.py", line 102, in <module> 
    parser.advance() 
    File "Assembler.py", line 15, in advance 
    self.command = self.asm_file[self.index] 
IndexError: list index out of range 

Я не совсем уверен, почему это за пределами допустимого диапазона. Все, что я кладу в командной строке является:

python Assembler.py MyFile.asm 

Может кто-то посмотреть на мой код ниже, и помочь мне понять, почему это дает мне это?

class Parser: 
def __init__(self, filename): 
    self.asm_file = [line for line in open(filename)] 
    self.index = 0 

def hasMoreCommands(self): 
    return self.index < len(self.asm_file) 

def advance(self): 
    self.index += 1 

    if self.index == len(self.asm_file): 
     return 

    self.command = self.asm_file[self.index] 
    self.command = self.removeCommentsAndSpaces(self.command) 

    if not self.command: 
     self.advance() 

Там просто больше определений коды между этими блоками, и линия 102, указанная в сообщении об ошибке в строке 10 следующего блок.

if __name__ == '__main__': 
import sys 

if len(sys.argv) == 1: 
    print 'need filename' 
    sys.exit(-1) 

table = SymbolTable() 
parser = Parser(sys.argv[1]) 
parser.advance() 
line = 0 

while parser.hasMoreCommands(): 
    if parser.commandType() == 'L_COMMAND': 
     table.addEntry(parser.symbol(), line) 
    else: 
     line += 1 

    parser.advance() 

code = Code() 
parser = Parser(sys.argv[1]) 
parser.advance() 

var_stack = 16 

while parser.hasMoreCommands(): 
    cmd_type = parser.commandType() 

    if cmd_type == 'A_COMMAND': 
     number = 32768 

     try: 
      addr = int(parser.symbol()) 
     except: 
      if table.contains(parser.symbol()): 
       addr = table.getAddress(parser.symbol()) 
      else: 
       table.addEntry(parser.symbol(), var_stack) 
       addr = var_stack 
       var_stack += 1 

     bin_number = bin(number | addr)[3:] 
     assembly = '0' + bin_number 
     print assembly 
    elif cmd_type == 'C_COMMAND': 
     assembly = '111' 
     assembly += code.comp(parser.comp()) 
     assembly += code.dest(parser.dest()) 
     assembly += code.jump(parser.jump()) 
     print assembly 

    parser.advance() 
+0

Возможно ли, что 'index' превышает длину' asm_file' без соответствия его * точно *? Если это так, вы ожидаете увидеть ошибку, которую вы получаете. Попробуйте изменить 'if self.index == len (self.asm_file)' to 'if self.index> = len (self.asm_file)' –

ответ

0

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

def advance(self): 


if self.index == len(self.asm_file): 
    return 

self.command = self.asm_file[self.index] 
self.command = self.removeCommentsAndSpaces(self.command) 

self.index += 1 

if not self.command: 
    self.advance() 

И почему бы не повторить код? Второй способ:

def advance(self): 
self.index += 1 

if not self.hasMoreCommands(): 
    return 

self.command = self.asm_file[self.index] 
self.command = self.removeCommentsAndSpaces(self.command) 



if not self.command: 
    self.advance() 
0
self.index += 1 

if self.index == len(self.asm_file): 
    return 

self.command = self.asm_file[self.index] 

Как вы проверяете индекс сразу после приращения и перед обращением к списку, можно было бы предположить, что вы делаете хорошо. Однако, что может быть проблемой здесь, так это то, что до увеличения значения индекса вы уже находитесь в конце списка. Таким образом, после увеличения индекса индекс больше, чем длина списка.

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

if self.index >= len(self.asm_file): 
    return 

В самом деле, ваша проблема возникает в строке 10 этого последнего фрагмента, то есть здесь:

parser = Parser(sys.argv[1]) 
parser.advance() 

Учитывая, что вы заранее только один раз, очень вероятно, что файл пуст, т. е. длина списка равна нулю. Поэтому, когда вы продвигаетесь один раз, у вас есть индекс 1, который не равен длине (0), но по-прежнему находится за пределами диапазона для доступа к списку.