SET, GET, ALIAS = ("SET", "GET", "ALIAS") INTEGER = "INTEGER" EOF = "EOF" class Token(object): def __init__(self, type, value): self.type = type self.value = value def __str__(self): return f"Token({self.type}, {self.value}" def __repr__(self) -> str: return self.__str__() class Lexer(object): def __init__(self, text): self.text = text self.pos = 0 self.current_char = self.text[self.pos] def error(self): raise Exception("Invalid Character") def advance(self): """Advance the `pos` pointer and set the `current_char` variable.""" self.pos += 1 if self.pos > len(self.text) - 1: self.current_char = None # Indicates end of input else: self.current_char = self.text[self.pos] def skip_whitespace(self): while self.current_char is not None and self.current_char.isspace(): self.advance() def integer(self): """Return a (multidigit) integer consumed from the input.""" result = "" while self.current_char is not None and self.current_char.isdigit(): result += self.current_char self.advance() return int(result) def get_next_token(self): """Lexical analyzer (also known as scanner or tokenizer) This method is responsible for breaking a sentence apart into tokens. One token at a time. """ while self.current_char is not None: if self.current_char.isspace(): self.skip_whitespace() continue if self.current_char.isdigit(): return Token(INTEGER, self.integer()) if self.current_char == "get": self.advance() return Token(GET, "get") if self.current_char == "set": self.advance() return Token(SET, "set") if self.current_char == "Alias": self.advance() return Token(ALIAS, "Alias") self.error() return Token(EOF, None)