从未在python中执行的文件中读取的两个代码块中的第一个

时间:2016-07-02 01:55:39

标签: python file assembly io

作为赋值的一部分,我在python中编写汇编程序,它使用简化的汇编语言并输出二进制机器语言。我的部分代码如下所示,我在两遍中从汇编代码中读取。从文件asm_file读取的第一个块中的第一行(open(filename,“r”)的第一行作为asm_file)似乎没有执行。第二个是执行正常,它没有输出正确的二进制文件,因为第一个块似乎没有正确运行或根本没有。我使用“with open(filename。”r“)作为文件:”正确吗?我错过了什么?提前谢谢。

为了完整性,在代码下面给出了一个输入文件:

if __name__ == "__main__":
    #fill Symbol Table and C instruction Tables
    symbol_table = symbolTable()
    symbol_table.initialiseTable()

    comp_table = compTable()
    comp_table.fillTable()

    dest_table = destTable()
    dest_table.fillTable()

    jump_table = jumpTable()
    jump_table.fillTable()

    #import the file given in the command line
    filename = sys.argv[-1]
    #open output_file
    output_file = open('output.hack', 'w')
    #open said file and work on contents line by line
    with open(filename, "r") as asm_file:   ##### This one doesn't seem to run because
        #1st pass of input file    ##### The print command below doesn't output anything
        num_instructions = -1
        for line in asm_file:
            #ignoring whitespace and comments
            if line != '\n' and not line.startswith('//'):
                num_instructions += 1
                #remove in-line comments
                if '//' in line:
                    marker, line = '//', line
                    line = line[:line.index(marker)].strip()
                    #search for beginning of pseudocommand
                    if line.startswith('('):
                        num_instructions -= 1
                        label = line.strip('()')
                        address = num_instructions + 1
                        symbol_table.addLabelAddresses(label, address)
                        print(num_instructions)   ###### This print command doesn't output anything

    with open(filename, "r") as asm_file:   
        #2nd pass of input file
        for line in asm_file:
            #ignoring whitespace and comments
            if line != '\n' and not line.startswith('//') and not line.startswith('('):
                #remove in-line comments
                if '//' in line:
                    marker, line = '//', line
                    line = line[:line.index(marker)].strip()
                #send each line to parse function to unpack into its underlying fields  
                instruction = parseLine(line.strip(' \n'))
                inst = Instruction(instruction)
                binary_string = inst.convertToBin()
                #write to output file
                output_file.write(binary_string +'\n')

    output_file.close()

输入文件示例:

// This file is part of www.nand2tetris.org

    // and the book "The Elements of Computing Systems"

    // by Nisan and Schocken, MIT Press.

    // File name: projects/06/max/Max.asm



    // Computes R2 = max(R0, R1)  (R0,R1,R2 refer to  RAM[0],RAM[1],RAM[2])



       @R0

       D=M              // D = first number

       @R1

       D=D-M            // D = first number - second number

       @OUTPUT_FIRST

       D;JGT            // if D>0 (first is greater) goto output_first

       @R1

       D=M              // D = second number

       @OUTPUT_D

       0;JMP            // goto output_d

    (OUTPUT_FIRST)

       @R0             

       D=M              // D = first number

    (OUTPUT_D)

       @R2

       M=D              // M[2] = D (greatest number)

    (INFINITE_LOOP)

       @INFINITE_LOOP

       0;JMP            // infinite loop

2 个答案:

答案 0 :(得分:1)

您的问题似乎是您的代码检查一行是否以(开头,但在程序集中它在指令之前有一个选项卡,因此它不起作用。您应该在第一个if语句之后执行line.strip(),如此

with open(filename, "r") as asm_file:
    num_of_instructions = -1
    for line in asm_file
        if line != "\n":
            line.strip()
            #rest of code

顺便说一下,每次找到一行时都应该执行print语句吗?因为如果没有,你应该把它放在for循环之后。这就是为什么它没有输出任何东西

编辑:正如@TimPeters所说,如果print语句以一个开括号开头并且其中有注释,那么print语句也只会执行

答案 1 :(得分:0)

在第一个with中,从

开始
#search for beginning of pseudocommand

你确定你不希望这样,以下几行会缩小一个级别吗?

按原样,到达print的唯一方法是,如果一行符合两者

if '//' in line:

if line.startswith('('):

输入文件中没有任何行满足两者,因此print永远不会执行。

在第二个with中, 之后只有两个缩进行

if '//' in line: