0

機械語をアセンブリ言語に変換するコードを作成しましたが、コマンド プロンプトから実行しようとするとエラーが発生し続けます。私が受け取っているエラーは次のとおりです。

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

2 に答える 2

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

そして、なぜコードを再利用しませんか?2番目の方法:

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()
于 2013-02-23T23:42:01.847 に答える
0
self.index += 1

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

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

インクリメントの直後でリストにアクセスする前にインデックスをチェックすると、うまくやっていると思われます。ただし、ここで問題になる可能性があるのは、インデックス値をインクリメントする前に、すでにリストの長さに達していることです。したがって、インクリメントした後、インデックスはリストの長さよりも 1 大きくなります。

リストにアクセスする前にインデックスを印刷することで、簡単に確認できます。安全なルートに行くには、チェックを変更するだけです:

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

実際、問題は最後のスニペットの 10 行目、つまり次の場所で発生します。

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

1 回だけ進む場合、ファイルが空である可能性が非常に高くなります。つまり、リストの長さがゼロです。したがって、一度進むと、インデックスは1になります。これは、長さ ( ) と等しくありません0が、リスト アクセスの範囲外です。

于 2013-02-23T23:47:53.737 に答える