アセンブラを作る / Parserクラス完成
要領が分かったのでParserクラスのメソッドを全部作る。
class Parser: def __init__(self, file_path): self.file = open(file_path, "r") self.file.seek(0, 2) self.EOF_POS = self.file.tell() self.file.seek(0) self.current_inst = "" def __readline_scrapeoff(self): line = self.file.readline() # 先頭の空白と末尾の改行記号とを削除する。 line = line.strip() # コメントを削除する line = line.split("//")[0] # 文字列中のスペースを削除する。 line = line.replace(" ", "") # 文字列中のタブ文字を削除する。 line = line.replace("\t", "") return line if line else None def has_more_lines(self): return self.file.tell() != self.EOF_POS def advance(self): self.current_inst = self.__readline_scrapeoff() def inst_type(self): # 空行ならNoneを返す。 if not self.current_inst: return None # @があったらA命令。 elif "@" in self.current_inst: return "A" # (~)があったらL命令。 elif ("(" in self.current_inst) and (")" in self.current_inst): return "L" # それ以外ならC命令。 else: return "C" def symbol(self): if self.inst_type() == "A": # @の次の文字以降を返す。 return self.current_inst[1:] elif self.inst_type() == "L": # (の次から)の手前までを返す。 return self.current_inst[1:-1] def dest(self): # 格納先が指定してあったら=の左辺を返す。 if (self.inst_type() == "C") and ("=" in self.current_inst): return self.current_inst.split("=")[0] def comp(self): # dest=comp;jump if self.inst_type() == "C": # destを切り落とす。 comp_part = self.current_inst.split("=")[-1] # jumpを切り落とす。 comp_part = comp_part.split(";")[0] return comp_part def jump(self): # ジャンプ先が指定してあったら;の右側を返す。 if (self.inst_type() == "C") and (";" in self.current_inst): return self.current_inst.split(";")[-1] def close(self): self.file.close() ################################################### if __name__ == "__main__": s = Parser("test.asm") while (s.has_more_lines()): s.advance() print("命令 :", s.current_inst) print("命令タイプ :", s.inst_type()) print("シンボル :", s.symbol()) print("格納先 :", s.dest()) print("ALU出力 :", s.comp()) print("ジャンプ命令:", s.jump()) print("") s.close()
テストファイル:
@2 D=A @3 D=D+A (LOOP) @0 M=D @LOOP 0;JMP // 以下はテスト dest=comp;jump comp;jump dest=comp comp
実行結果:
命令 : @2 命令タイプ : A シンボル : 2 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : D=A 命令タイプ : C シンボル : None 格納先 : D ALU出力 : A ジャンプ命令: None 命令 : @3 命令タイプ : A シンボル : 3 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : D=D+A 命令タイプ : C シンボル : None 格納先 : D ALU出力 : D+A ジャンプ命令: None 命令 : (LOOP) 命令タイプ : L シンボル : LOOP 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : @0 命令タイプ : A シンボル : 0 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : M=D 命令タイプ : C シンボル : None 格納先 : M ALU出力 : D ジャンプ命令: None 命令 : @LOOP 命令タイプ : A シンボル : LOOP 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : 0;JMP 命令タイプ : C シンボル : None 格納先 : None ALU出力 : 0 ジャンプ命令: JMP 命令 : None 命令タイプ : None シンボル : None 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : None 命令タイプ : None シンボル : None 格納先 : None ALU出力 : None ジャンプ命令: None 命令 : dest=comp;jump 命令タイプ : C シンボル : None 格納先 : dest ALU出力 : comp ジャンプ命令: jump 命令 : comp;jump 命令タイプ : C シンボル : None 格納先 : None ALU出力 : comp ジャンプ命令: jump 命令 : dest=comp 命令タイプ : C シンボル : None 格納先 : dest ALU出力 : comp ジャンプ命令: None 命令 : comp 命令タイプ : C シンボル : None 格納先 : None ALU出力 : comp ジャンプ命令: None