简体   繁体   English

我在Python中收到索引错误,说它超出范围,但是我不确定为什么

[英]I'm getting an index error in Python saying that it's out of range, but I'm not sure why

I've created code that's supposed to turn a machine language into an assembly language, but I keep getting an error when I try to run it from the command prompt. 我创建了应该将机器语言转换为汇编语言的代码,但是当我尝试从命令提示符运行它时,我总是收到错误消息。 The error I'm receiving is: 我收到的错误是:

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

I'm not really sure why it's out of range though. 我不太确定为什么它超出范围。 All I'm putting into the command prompt is: 我要输入的命令提示符是:

 python Assembler.py MyFile.asm

Can someone look at my code below and help me figure out why it's giving me this? 有人可以看下面我的代码并帮助我弄清楚为什么它给了我吗?

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()

There's just more code definitions in between these blocks, and the line 102 referenced in the error message is line 10 of the following block. 在这些块之间只有更多的代码定义,错误消息中引用的第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()

You trying to access at the end of the script a line further then lines exist. 您尝试在脚本末尾访问一行,然后再访问几行。 So try to move your increment of index at the end of the function. 因此,请尝试在函数末尾移动索引的增量。

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()

And why not reeusing code? 为什么不重新编写代码? Second way: 第二种方式:

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()
self.index += 1

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

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

As you check your index right after incrementing and before accessing the list, one would assume that you are doing fine. 当您在增加索引之后以及访问列表之前立即检查索引时,您会认为您做得不错。 However what might be the problem here is that before incrementing the index value, you are already at the length of the list. 但是,这里可能存在的问题是,在增加索引值之前,您已经处于列表长度上。 So after incrementing the index is one bigger than the list length. 因此,索引增加后比列表长度大一。

You could easily check that by printing out the index before accessing the list. 您可以通过在访问列表之前打印出索引来轻松地进行检查。 To go the safe route, just change your check though: 为了安全起见,只需更改支票即可:

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

In fact, your issue occurs on line 10 of that last snippet, ie here: 实际上,您的问题发生在最后一个代码段的第10行,即此处:

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

Given that you advance only once, it's very likely that the file is empty, ie the length of the list is zero. 假设您只前进一次,则文件很可能为空,即列表的长度为零。 So when you advance once, you have an index of 1 , which is not equal to the length ( 0 ) but is still out of range for the list access. 因此,当您前进一次时,索引为1 ,它不等于长度( 0 ),但仍超出列表访问范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM