class Context(): def __init__(self, text: str): self.__tokenizer = Tokenizer(text) self.__currentToken = None self.nextToken() def nextToken(self) -> str: if self.__tokenizer.hasMoreTokens(): self.__currentToken = self.__tokenizer.nextToken() else: self.__currentToken = None return self.__currentToken def currentToken(self) -> str: return self.__currentToken def skipToken(self, token: str) -> None: if not token == self.__currentToken: raise ParseException( "Warning {} is expected, but {} is found".format( token, self.__currentToken)) self.nextToken() def currentNumber(self) -> int: number: int = 0 try: number = int(self.__currentToken) except ValueError as e: raise ParseException("Warning: " + str(e)) return number
class Parser(): def __init__(self, Filebuffer): self.File = Filebuffer self.Tokenizer = Tokenizer(Filebuffer) self.operand = Operands() def parse(self): statements = [] while 1: Token = self.Tokenizer.nextToken() if Token.Get_Token_Type() == TokenType.EOF: break if Token.Get_Token_Type() == TokenType.Mnemonic: # statement -> mnemonic (%register | $decimal) , %register operands = [] opcode = Token.Get_Token_value() Token = self.Tokenizer.nextToken() # source have adress displacement , in this case Mnemonic means label if Token.Get_Token_Type( ) == TokenType.Disp or Token.Get_Token_Type( ) == TokenType.Mnemonic: disp = Token.Get_Token_value() Token = self.Tokenizer.nextToken() Token.match(TokenType.LPAREN) Token = self.Tokenizer.nextToken() operand = self.operand.MakeOperand(Token.Get_Token_Type(), Token.Get_Token_value()) operands.append(Address(operand, disp, None, None)) Token = self.Tokenizer.nextToken() Token.match(TokenType.RPAREN) elif Token.Get_Token_Type() == TokenType.LPAREN: Token = self.Tokenizer.nextToken() operand = self.operand.MakeOperand(Token.Get_Token_Type(), Token.Get_Token_value()) print(self.Tokenizer.look2ahead().Get_Token_Type()) if self.Tokenizer.look2ahead().Get_Token_Type( ) == TokenType.Register: basereg = operand Token = self.Tokenizer.nextToken() Token.match(TokenType.Comma) Token = self.Tokenizer.nextToken() indexreg = self.operand.MakeOperand( Token.Get_Token_Type(), Token.Get_Token_value()) Token = self.Tokenizer.nextToken() Token.match(TokenType.Comma) Token = self.Tokenizer.nextToken() scale = self.operand.MakeOperand( Token.Get_Token_Type(), Token.Get_Token_value()) operands.append(Address(operand, None, indexreg, scale)) Token = self.Tokenizer.nextToken() Token.match(TokenType.RPAREN) else: operands.append(Address(operand, None, None, None)) Token = self.Tokenizer.nextToken() Token.match(TokenType.RPAREN) elif Token.Get_Token_Type( ) == TokenType.Register or Token.Get_Token_Type( ) == TokenType.Number: Token.match(TokenType.Register, TokenType.Number) operands.append( self.operand.MakeOperand(Token.Get_Token_Type(), Token.Get_Token_value())) if self.Tokenizer.lookahead().Get_Token_Type( ) == TokenType.NewLine: statements.append(Intruction(opcode, operands)) self.Tokenizer.nextToken() continue if self.Tokenizer.lookahead().Get_Token_Type( ) == TokenType.EOF: statements.append(Intruction(opcode, operands)) self.Tokenizer.nextToken() break Token = self.Tokenizer.nextToken() Token.match(TokenType.Comma) Token = self.Tokenizer.nextToken() Token.match(TokenType.Register) operands.append( self.operand.MakeOperand(Token.Get_Token_Type(), Token.Get_Token_value())) Token = self.Tokenizer.nextToken() statements.append(Intruction(opcode, operands)) if Token.Get_Token_Type() == TokenType.EOF: break Token.match(TokenType.NewLine) return statements