interpreter.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from .tokens import TokenType, Token
  2. class InterpreterException(Exception):
  3. pass
  4. class Interpreter():
  5. def __init__(self):
  6. self._pos: int = -1
  7. self._current_token: Token = None
  8. self._current_char: str = None
  9. self._text: str = ""
  10. def _next_token(self) -> Token:
  11. while self._current_char is not None:
  12. self._current_char: str = self._text[self._pos]
  13. if self._current_char.isdigit():
  14. self._forward()
  15. return Token(TokenType.INTEGER, self._current_char)
  16. if self._current_char == "+":
  17. self._forward()
  18. return Token(TokenType.PLUS, self._current_char)
  19. if self._current_char == "-":
  20. self._forward()
  21. return Token(TokenType.MINUS, self._current_char)
  22. raise InterpreterException(f"bad token {self._current_char}")
  23. return Token(TokenType.EOS, None)
  24. def _forward(self):
  25. self._pos += 1
  26. if self._pos >= len(self._text):
  27. self._current_char = None
  28. else:
  29. self._current_char = self._text[self._pos]
  30. def _check_token_type(self, type_: TokenType):
  31. if self._current_token.type_ == type_:
  32. self._current_token = self._next_token()
  33. else:
  34. raise InterpreterException("invalid token order")
  35. def _expr(self) -> int:
  36. self._current_token = self._next_token() # берём первый токен
  37. left = self._current_token
  38. self._check_token_type(TokenType.INTEGER)
  39. op = self._current_token
  40. if op.type_ == TokenType.PLUS:
  41. self._check_token_type(TokenType.PLUS)
  42. else:
  43. self._check_token_type(TokenType.MINUS)
  44. right = self._current_token
  45. self._check_token_type(TokenType.INTEGER)
  46. if op.type_ == TokenType.PLUS:
  47. return int(left.value) + int(right.value)
  48. elif op.type_ == TokenType.MINUS:
  49. return int(left.value) - int(right.value)
  50. raise InterpreterException("bad operator")
  51. def __call__(self, text: str):
  52. return self.interpret(text)
  53. def interpret(self, text: str):
  54. self._text = text
  55. self._pos = -1
  56. self._forward()
  57. return self._expr()