class Parser(): '''Class Parser look at next token''' A_COMMAND = 0 C_COMMAND = 1 L_COMMAND = 2 def __init__(self, file): self.lex = Lexicon(file) self._init_cmd_info() def _init_cmd_info(self): self._cmd_type = -1 self._symbol = '' self._dest = '' self._comp = '' self._jmp = '' def __str__(self): pass def has_more_commands(self): return self.lex.has_more_commands() # Get the next entire command - each command resides on its own line. def advance(self): self._init_cmd_info() self.lex.next_command() tok, val = self.lex.cur_token if tok == self.lex.OP and val == '@': self._a_command() elif tok == self.lex.OP and val == '(': self._l_command() else: self._c_command(tok, val) # The following functions contain the extracted parts of the command. def command_type(self): return self._cmd_type def symbol(self): return self._symbol def dest(self): return self._dest def comp(self): return self._comp def jmp(self): return self._jmp # @symbol or @number def _a_command(self): self._cmd_type = Parser.A_COMMAND tok_type, self._symbol = self.lex.next_token() # (symbol) def _l_command(self): self._cmd_type = Parser.L_COMMAND tok_type, self._symbol = self.lex.next_token() # dest=comp;jump # dest=comp omitting jump # comp;jump omitting dest # comp omitting dest and jump def _c_command(self, tok1, val1): self._cmd_type = Parser.C_COMMAND comp_tok, comp_val = self._get_dest(tok1, val1) self._get_comp(comp_tok, comp_val) self._get_jump() # Get the 'dest' part if any. Return the first token of the 'comp' part. def _get_dest(self, tok1, val1): tok2, val2 = self.lex.peek_token() if tok2 == self.lex.OP and val2 == '=': self.lex.next_token() self._dest = val1 comp_tok, comp_val = self.lex.next_token() else: comp_tok, comp_val = tok1, val1 return (comp_tok, comp_val) # Get the 'comp' part - must be present. def _get_comp(self, tok, val): if tok == self.lex.OP and (val == '-' or val == '!'): tok2, val2 = self.lex.next_token() self._comp = val + val2 elif tok == self.lex.NUM or tok == self.lex.ID: self._comp = val tok2, val2 = self.lex.peek_token() if tok2 == self.lex.OP and val2 != ';': self.lex.next_token() tok3, val3 = self.lex.next_token() self._comp += val2 + val3 # Get the 'jump' part if any def _get_jump(self): tok, val = self.lex.next_token() if tok == self.lex.OP and val == ';': jump_tok, jump_val = self.lex.next_token() self._jmp = jump_val