|
@@ -0,0 +1,67 @@
|
|
|
+from .tokens import TokenType, Token
|
|
|
+
|
|
|
+
|
|
|
+class InterpreterException(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class Interpreter():
|
|
|
+ def __init__(self):
|
|
|
+ self._pos: int = -1
|
|
|
+ self._current_token: Token = None
|
|
|
+ self._current_char: str = None
|
|
|
+ self._text: str = ""
|
|
|
+
|
|
|
+ def _next_token(self) -> Token:
|
|
|
+ while self._current_char is not None:
|
|
|
+ self._current_char: str = self._text[self._pos]
|
|
|
+ if self._current_char.isdigit():
|
|
|
+ self._forward()
|
|
|
+ return Token(TokenType.INTEGER, self._current_char)
|
|
|
+ if self._current_char == "+":
|
|
|
+ self._forward()
|
|
|
+ return Token(TokenType.PLUS, self._current_char)
|
|
|
+ if self._current_char == "-":
|
|
|
+ self._forward()
|
|
|
+ return Token(TokenType.MINUS, self._current_char)
|
|
|
+ raise InterpreterException(f"bad token {self._current_char}")
|
|
|
+ return Token(TokenType.EOS, None)
|
|
|
+
|
|
|
+ def _forward(self):
|
|
|
+ self._pos += 1
|
|
|
+ if self._pos >= len(self._text):
|
|
|
+ self._current_char = None
|
|
|
+ else:
|
|
|
+ self._current_char = self._text[self._pos]
|
|
|
+
|
|
|
+ def _check_token_type(self, type_: TokenType):
|
|
|
+ if self._current_token.type_ == type_:
|
|
|
+ self._current_token = self._next_token()
|
|
|
+ else:
|
|
|
+ raise InterpreterException("invalid token order")
|
|
|
+
|
|
|
+ def _expr(self) -> int:
|
|
|
+ self._current_token = self._next_token() # берём первый токен
|
|
|
+ left = self._current_token
|
|
|
+ self._check_token_type(TokenType.INTEGER)
|
|
|
+ op = self._current_token
|
|
|
+ if op.type_ == TokenType.PLUS:
|
|
|
+ self._check_token_type(TokenType.PLUS)
|
|
|
+ else:
|
|
|
+ self._check_token_type(TokenType.MINUS)
|
|
|
+ right = self._current_token
|
|
|
+ self._check_token_type(TokenType.INTEGER)
|
|
|
+ if op.type_ == TokenType.PLUS:
|
|
|
+ return int(left.value) + int(right.value)
|
|
|
+ elif op.type_ == TokenType.MINUS:
|
|
|
+ return int(left.value) - int(right.value)
|
|
|
+ raise InterpreterException("bad operator")
|
|
|
+
|
|
|
+ def __call__(self, text: str):
|
|
|
+ return self.interpret(text)
|
|
|
+
|
|
|
+ def interpret(self, text: str):
|
|
|
+ self._text = text
|
|
|
+ self._pos = -1
|
|
|
+ self._forward()
|
|
|
+ return self._expr()
|